STL векторный резерв () и копирование ()

Привет,

Я пытаюсь выполнить копирование из одного вектора (vec1) в другой вектор (vec2), используя следующие 2 сокращенные строки кода (полное тестовое приложение следует):

vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), vec2.begin());

Хотя вызов vec2 устанавливает емкость вектора vec2, копирование данных в vec2, по-видимому, не заполняет значения от vec1 до vec2.

Замена функции copy () вызовами push_back () работает как положено.

Что мне здесь не хватает?

Спасибо за вашу помощь. Далее следует тестовая программа vectest.cpp с последующим выводом.

Компилятор: gcc 3.4.4 на cygwin.

Nat
/**
 * vectest.cpp
 */

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec1;
    vector<int> vec2;

    vec1.push_back(1);
    vec1.push_back(2);
    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);
    vec1.push_back(6);
    vec1.push_back(7);

    vec2.reserve( vec1.size() );
    copy(vec1.begin(), vec1.end(), vec2.begin());

    cout << "vec1.size()     = " << vec1.size() << endl;
    cout << "vec1.capacity() = " << vec1.capacity() << endl;

    cout << "vec1: ";
    for( vector<int>::const_iterator iter = vec1.begin(); iter < vec1.end(); ++iter ) {
        cout << *iter << " ";
    }
    cout << endl;

    cout << "vec2.size()     = " << vec2.size() << endl;
    cout << "vec2.capacity() = " << vec2.capacity() << endl;
    cout << "vec2: ";
    for( vector<int>::const_iterator iter = vec2.begin(); iter < vec2.end(); ++iter ) {
        cout << *iter << endl;
    }

    cout << endl;
}

выход:

vec1.size()     = 7
vec1.capacity() = 8
vec1: 1 2 3 4 5 6 7 
vec2.size()     = 0
vec2.capacity() = 7
vec2: 

Ответы на вопрос(5)

На мой взгляд, самый простой способ - использовать метод std :: vector :: insert:

v2.insert(v2.end(), v1.begin(), v1.end());

(увидетьhttp://www.sgi.com/tech/stl/Vector.html)

Изменить резерв для изменения размера ():

vec2.resize(vec1.size(), '\0');
copy(vec1.begin(), vec1.end(), vec2.begin());

Я считаю, что это то, что вам нужно.

Я не могу дать вам очень хорошее описание различий, но, в основном, reserve () гарантирует, что у вас достаточно места, а resize () фактически что-то вставляет туда.

Если векторы одного типа, используйте конструкцию копирования или назначение копирования:

vec2(vec1);
vec2 = vec1;

Если векторы не совпадают (может быть, другой распределитель или что-то, или vec1 является deque), то вам действительно нужен конструктор на основе диапазона или присвоение на основе диапазона:

vec2(vec1.begin(), vec1.end()); // range-based constructor

vec2.assign(vec1.begin(), vec1.end()); // range-based assignment

Если вы настаиваете на том, чтобы сделать это сstd::copyправильный метод:

copy(vec1.begin(), vec1.end(), back_inserter(vec2));

Поскольку резервирование места не делает его назначаемым.copy работает, присваивая каждому элементу его новое значение. Такvec2.size() должно быть не меньше, чемvec1.size() в твоем случае. призваниеreserve фактически не меняет размер вектора, только его емкость.

В книгеEffective STLСкотт Мейерс утверждает, что почти все случаи использования std :: copy для вставки должны быть заменены функциями-членами на основе диапазона. Я предлагаю вам взять копию, это отличная ссылка!

 15 апр. 2016 г., 09:58
Я думаю, что вы должны подчеркнуть "функции-члены" в последнем абзаце я сначала пропустил это и подумал: «Что? копияis Диапазон на основе & Quot!; Это отличная рекомендация, поэтому мы не хотим, чтобы люди ее пропустили :)
Решение Вопроса

Как отмечено в других ответах и комментариях, вы должны просто использовать для этого встроенную функциональность вектора. Но:

Когда тыreserve() элементы, вектор выделит достаточно места для (по крайней мере?) такого количества элементов. Элементы не существуют в векторе, но память готова к использованию. Это, возможно, ускоритpush_back() потому что память уже выделена.

Когда тыresize() вектор, он выделит достаточно места для этих элементов,but also add them to the vector.

Таким образом, если вы измените размер вектора до 100, вы сможете получить доступ к элементам 0 - 99, но если вы зарезервируете 100 элементов, они еще не вставлены, просто готовы к использованию.

То, что вы хотите, это что-то вроде этого:

vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), std::back_inserter(vec2));

std::back_inserter определяется в<iterator>

 29 мая 2013 г., 17:10
по какой-то причинеvec2.begin() не компилируется, а простоvec2 работает
 15 июл. 2009 г., 01:15
+1, спасибо за резервную копию: P
 15 июл. 2009 г., 01:19
Хех, да Сначала я тоже понял разницу.
 15 июл. 2009 г., 03:13
Вы действительно должны использоватьvec2.assign или жеvec2.insert вместо этого ... они более оптимизированы.
 natersoz15 июл. 2009 г., 01:34
Эврика - это сработало. Не только в опубликованном тестовом приложении, но и в более сложном проблемном приложении, которое у меня было. Я избегал использования resize (), так как это добавляет элементы, где я не собирался добавлять. Спасибо за образование.

Почему бы и нет:vec2 = vec1; ?

 15 июл. 2009 г., 01:04
Да, это очень хорошо: D, но оно действительно иллюстрирует разницу между векторами resize () и reserve (), которые привели меня в чувство на несколько часов.
 natersoz15 июл. 2009 г., 01:36
Это также было полезно для меня, хотя я не знал, что такое копия ctor. Благодарю.
 15 июл. 2009 г., 01:02
Groundbreaking!
 09 июл. 2013 г., 19:47
Просто и элегантно. Странно, что такие простые вещи никогда не бывают очевидными и понятными в C ++.

Ваш ответ на вопрос