如何将数组的内容复制到C ++中的std :: vector而不循环?
我有一个值的数组,从我需要存储以供日后处理的程序的不同部分传递给我的函数。 由于我不知道在处理数据之前我的函数会被调用多less次,所以我需要一个dynamic的存储结构,所以我select了一个std::vector
。 我不想做标准循环push_back
单独的所有值,这将是很好,如果我可以使用类似于memcpy
全部复制它。
如果可以在获得数组和数组大小后构造向量,则可以这样说:
std::vector<ValueType> vec(a, a + n);
假设a
是你的数组, n
是它包含的元素的数量。 否则, std::copy()
w / resize()
将会诀窍。
除非可以确定这些值是普通数据(POD)types,否则我会远离memcpy()
。
另外,值得注意的是,这些都没有真正避免for循环 – 这只是一个问题,你是否必须在你的代码中看到它。 O(n)运行时的性能是不可避免的复制的值。
最后,注意C风格的数组对于大多数STLalgorithm来说是完全有效的容器 – 原始指针相当于begin()
,而( ptr + n
)相当于end()
。
这里有很多答案,几乎所有的答案都可以完成。
不过有一些误导性的build议!
这里是选项:
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,使用vector :: insert,对于bsruth的场景是最好的。
这里有一些血淋淋的细节:
方法1可能是最容易理解的。 只需复制数组中的每个元素,并将其推入vector的后面。 唉,这很慢。 因为有一个循环(隐含的复制function),每个元素必须单独处理; 基于我们知道数组和向量是连续块的事实,不能进行性能改进。
方法2是方法1的build议性能改进; 只是在添加之前预先保留了数组的大小。 对于大型数组,这可能会有帮助 然而,这里最好的build议是从来没有使用储备,除非分析表明你可能能够得到改善(或者你需要确保你的迭代器不会失效)。 Bjarne同意 。 顺便说一下,我发现这种方法执行最慢的时间,尽pipe我正在努力全面解释为什么它经常比方法1慢得多…
方法3是旧的解决scheme – 抛出一些C的问题! 为PODtypes正常工作。 在这种情况下,resize需要被调用,因为memcpy在向量的范围之外工作,并且无法告诉向量其大小已经改变。 除了是一个丑陋的解决scheme(字节复制!)记住,这只能用于PODtypes 。 我永远不会使用这个解决scheme。
方法4是最好的方法。 它的含义很清楚,通常是最快的,适用于任何物体。 在这个应用程序中使用这种方法没有缺点。
方法5是对方法4的调整 – 将数组复制到一个向量中,然后附加它。 好的select – 通常快速清晰。
最后,你知道你可以使用vector来代替数组,对吗? 即使函数期望c样式的数组,你也可以使用vector:
vector<char> v(50); // Ensure there's enough space strcpy(&v[0], "prefer vectors to c arrays");
希望能帮助那里的人!
如果你正在做的是取代现有的数据,那么你可以做到这一点
std::vector<int> data; // evil global :) void CopyData(int *newData, size_t count) { data.assign(newData, newData + count); }
std :: copy是你在找什么。
由于我只能编辑自己的答案,所以我要从我的问题的其他答案中作出综合答案。 感谢所有回答你的人。
使用std :: copy ,这仍然在后台迭代,但是你不必input代码。
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 。 这最好用于基本数据types(如int),但不适用于更复杂的结构或类的数组。
vector<int> x(size); memcpy(&x[0], source, size*sizeof(int));
避免memcpy,我说。 没有理由乱指针操作,除非你真的必须。 此外,它只会用于PODtypes(如int),但如果处理需要构build的types则会失败。
除了上面介绍的方法之外,还需要确保使用std :: Vector.reserve(),std :: Vector.resize(),或者构造向量的大小,以确保向量具有足够的元素它来保存你的数据。 如果不是的话,你会损坏记忆。 std :: copy()或memcpy()都是如此。
这是使用vector.push_back()的原因,你不能写过去的vector结束。
又一个答案,因为人说:“我不知道我的函数将被调用多less次”,你可以使用vector插入方法像这样的值的数组追加到vector的末尾:
vector<int> x; void AddValues(int* values, size_t size) { x.insert(x.end(), values, values+size); }
我喜欢这种方式,因为vector的实现应该能够根据迭代器types和types自身来插入值的最佳方式进行优化。 你对stl的实现有点回复。
如果你需要保证最快的速度,你知道你的types是一个PODtypes,那么我会build议在托马斯的答案resize的方法:
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)); }
int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//source unsigned dataArraySize = sizeof(dataArray) / sizeof(int); std::vector<int> myvector (dataArraySize );//target std::copy ( myints, myints+dataArraySize , myvector.begin() ); //myvector now has 1,2,3,...10 :-)
假设你知道向量中的项目有多大:
std::vector<int> myArray; myArray.resize (item_count, 0); memcpy (&myArray.front(), source, item_count * sizeof(int));