Если можно создать вектор после того, как Вы получили массив и выстраиваете размер, можно просто сказать:
std::vector<ValueType> vec(a, a + n);
... принятие a
является Вашим массивом, и n
число элементов, которое это содержит. Иначе std::copy()
w / resize()
добьется цели.
я избегал бы memcpy()
, если Вы не можете быть уверены, что значения являются типами простых данных (POD).
кроме того, стоящий замечания, что ни один из них действительно не избегает для цикла - это - просто вопрос того, необходимо ли видеть его в коде или нет. O (n) производительность во время выполнения неизбежно для копирования значений.
Наконец, обратите внимание, что массивы C-стиля являются совершенно допустимыми контейнерами для большинства алгоритмов STL - необработанный указатель эквивалентен begin()
, и (ptr + n
) эквивалентно end()
.
Если все, что Вы делаете, заменяет существующие данные, то можно сделать это
std::vector<int> data; // evil global :)
void CopyData(int *newData, size_t count)
{
data.assign(newData, newData + count);
}
Было много ответов здесь, и примерно все они сделают задание.
Однако существует некоторый вводящий в заблуждение совет!
Вот опции:
vector<int> dataVec;
int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
unsigned dataArraySize = sizeof(dataArray) / sizeof(int);
// Method 1: Copy the array to the vector using back_inserter.
{
copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}
// Method 2: Same as 1 but pre-extend the vector by the size of the array using reserve
{
dataVec.reserve(dataVec.size() + dataArraySize);
copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}
// Method 3: Memcpy
{
dataVec.resize(dataVec.size() + dataArraySize);
memcpy(&dataVec[dataVec.size() - dataArraySize], &dataArray[0], dataArraySize * sizeof(int));
}
// Method 4: vector::insert
{
dataVec.insert(dataVec.end(), &dataArray[0], &dataArray[dataArraySize]);
}
// Method 5: vector + vector
{
vector<int> dataVec2(&dataArray[0], &dataArray[dataArraySize]);
dataVec.insert(dataVec.end(), dataVec2.begin(), dataVec2.end());
}
, Короче говоря, Метод 4, с помощью вектора:: вставьте, является лучшим для сценария bsruth.
Вот некоторые окровавленные детали:
Метод 1 является, вероятно, самым легким понять. Просто скопируйте каждый элемент с массива и продвиньте его в заднюю часть вектора. Увы, это медленно. Поскольку существует цикл (подразумеваемый с функцией копии), каждый элемент нужно рассматривать индивидуально; никакие повышения производительности не могут быть сделаны на основе того, что мы знаем массив, и векторы являются непрерывными блоками.
Метод 2 является предложенным повышением производительности к Методу 1; просто предварительно зарезервируйте размер массива прежде, чем добавить его. Для больших массивов это могло бы справка. Однако лучший совет здесь никогда не состоит в том, чтобы использовать резерв, если профилирование не предполагает, что можно быть в состоянии получить улучшение (или необходимо удостовериться, что итераторы не будут недействительными). Bjarne соглашается . Кстати, я нашел, что этот метод работал самый медленный большую часть времени, хотя я изо всех сил пытаюсь всесторонне объяснить, почему это регулярно было значительно медленнее, чем метод 1...
Метод 3 является старым школьным решением - бросают некоторый C в проблему! Хорошо работает и быстро для типов POD. В этом случае измените размеры, требуется, чтобы быть названным с тех пор memcpy работы вне границ вектора и нет никакого способа сказать вектору, что его размер изменился. Кроме того, чтобы быть ужасным решением (байт, копирующий!) помнят, что это может только использоваться для типов POD . Я никогда не использовал бы это решение.
Метод 4 является лучшим способом пойти. Это означает, ясно, это является (обычно) самым быстрым, и это работает на любые объекты. Нет никакой оборотной стороны к использованию этого метода для этого приложения.
Метод 5 является тонкой настройкой на Методе 4 - копируют массив в вектор и затем добавляют его. Хороший вариант - обычно быстрый выход и ясный.
Наконец, Вы знаете, что можно использовать векторы вместо массивов, правильно? Даже когда функция ожидает массивы c-стиля, можно использовать векторы:
vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");
Hope, которая помогает кому-то там!
Так как я могу только отредактировать свой собственный ответ, я собираюсь сделать составной ответ от других ответов до моего вопроса. Благодаря всем Вам, кто ответил.
Используя станд.:: копия , это все еще выполняет итерации в фоновом режиме, но Вы не должны выводить код.
int foo(int* data, int size)
{
static std::vector<int> my_data; //normally a class variable
std::copy(data, data + size, std::back_inserter(my_data));
return 0;
}
Используя регулярный memcpy. Это, вероятно, лучше всего используется для типов основных данных (т.е. интервал), но не для более сложных матриц структур или классов.
vector<int> x(size);
memcpy(&x[0], source, size*sizeof(int));
избегайте memcpy, говорю я. Никакая причина смешать с операциями указателя, если Вы действительно не имеете к. Кроме того, это будет только работать на типы POD (как интервал), но перестало бы работать, если Вы будете иметь дело с типами, которые требуют конструкции.
В дополнение к методикам, представленным выше, необходимо удостовериться, что Вы используете любой станд.:: Vector.reserve (), станд.:: Vector.resize (), или конструкция вектор к размеру, для проверки вектора имеет достаточно элементов в нем для содержания данных. в противном случае Вы повредите память. Это верно для любого станд.:: копия () или memcpy ().
Это - причина использовать вектор push_back (), Вы не можете записать мимо конца вектора.
Еще один ответ, так как человек сказал, "Что я не знаю, сколько раз будет вызвана моя функция", Вы могли использовать векторный метод вставки как так для добавления массивов значений до конца вектора:
vector<int> x;
void AddValues(int* values, size_t size)
{
x.insert(x.end(), values, values+size);
}
мне нравится этот путь, потому что реализация вектора должна быть в состоянии оптимизировать для лучшего способа вставить значения на основе типа итератора и самого типа. Вы несколько отвечаете на реализации stl.
, Если бы необходимо гарантировать самую быструю скорость и Вы знаете, что Ваш тип является типом POD тогда, я рекомендовал бы изменять размеры метод в ответе Thomas:
vector<int> x;
void AddValues(int* values, size_t size)
{
size_t old_size(x.size());
x.resize(old_size + size, 0);
memcpy(&x[old_size], values, size * sizeof(int));
}
Принятие Вас знает, насколько большой объект в векторе:
std::vector<int> myArray;
myArray.resize (item_count, 0);
memcpy (&myArray.front(), source, item_count * sizeof(int));