Векторный резерв STL() и копия()
Привет,
Я пытаюсь выполнить копию из одного вектора (vec1) в другой вектор (vec2), используя следующие две сокращенные строки кода (следующее тестовое приложение):
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.
Нат
/**
* 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:
Ответы
Ответ 1
Как отмечалось в других ответах и комментариях, для этого вам нужно просто использовать встроенные в векторные функции. Но:
Когда вы reserve()
элементы, вектор выделит достаточно места для (по крайней мере?), что многие элементы. Элементы не существуют в векторе, но память готова к использованию. Это, возможно, ускорит push_back()
, поскольку память уже выделена.
Когда вы resize()
вектор, он выделит достаточно места для этих элементов, , но также добавит их в вектор.
Итак, если вы измените размер вектора на 100, вы можете получить доступ к элементам 0 - 99, но если вы зарезервируете 100 элементов, они еще не вставлены, просто готовы к использованию.
Что вы хотите, это примерно так:
vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), std::back_inserter(vec2));
std::back_inserter
определяется в <iterator>
Ответ 2
Если векторы одного типа, используйте построение копирования или назначение копии:
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
фактически не меняет размер вектора, а только его емкость.
В книге "Эффективный STL" Скотт Майерс утверждает, что почти все виды использования std:: copy для вставки должны быть заменены функциями-членами на основе диапазонов. Я предлагаю вам получить копию, это отличная ссылка!
Ответ 3
Почему не: vec2 = vec1;
?
Ответ 4
Изменить резерв для изменения размера():
vec2.resize(vec1.size(), '\0');
copy(vec1.begin(), vec1.end(), vec2.begin());
Я считаю, что это исправление, в котором вы нуждаетесь.
Я не могу дать вам очень хорошее описание разницы, но в основном reserve() гарантирует, что у вас достаточно места, а resize() фактически вставляет что-то там.
Ответ 5
На мой взгляд, самый простой способ - использовать метод std::vector::insert
:
v2.insert(v2.end(), v1.begin(), v1.end());
(см. std::vector :: insert)