Answers:
如果可以在获得数组和数组大小之后构造向量,则可以说:
std::vector<ValueType> vec(a, a + n);
...假设a
是您的数组,n
是其中包含的元素数。否则,std::copy()
w / resize()
会成功。
memcpy()
除非您可以确定这些值是纯旧数据(POD)类型,否则我将远离。
此外,值得注意的是,这些方法都不能真正避免for循环-只是您是否必须在代码中看到它的问题。O(n)运行时性能对于复制值是不可避免的。
最后,请注意,C样式数组对于大多数STL算法都是完全有效的容器-原始指针等于begin()
,而(ptr + n
)等于end()
。
这里有很多答案,几乎所有答案都可以完成工作。
但是,有一些误导性建议!
以下是选项:
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可能是最容易理解的。只需复制数组中的每个元素,然后将其推入向量的背面即可。las,很慢。因为有一个循环(带有复制功能),所以每个元素都必须单独处理;我们知道数组和向量是连续的块,因此无法提高性能。
方法2是对方法1的建议性能改进;只需在添加之前预先保留阵列的大小即可。对于大型阵列,这可能会有所帮助。但是,这里最好的建议是永远不要使用储备,除非分析表明您可能会有所改进(或者您需要确保迭代器不会失效)。 Bjarne同意。顺便说一句,我发现这个方法执行的最慢的大部分时间,虽然我竭力要全面地解释为什么它是定期显著慢于法1 ...
方法3是老派的解决方案-在问题上扔一些C!对于POD类型,可以正常工作。在这种情况下,由于memcpy在向量的边界之外工作,并且无法告诉向量其大小已更改,因此需要调用resize。除了是一个丑陋的解决方案(字节复制!)之外,请记住,这只能用于POD类型。我永远不会使用此解决方案。
方法4是最好的方法。它的意思很清楚,它(通常)是最快的,并且适用于任何对象。在此应用程序中使用此方法没有任何弊端。
方法5是对方法4的调整-将数组复制到向量中,然后附加它。不错的选择-一般快速且清晰。
最后,您知道可以使用向量代替数组,对吗?即使函数期望使用c样式的数组,您也可以使用向量:
vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");
希望能帮助到那里的人!
&expr
不求值expr
,它仅计算它的地址。和一个指向一个过去的最后一个元素是完全有效的,太。
dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
–对我而言似乎更清晰。也不能从方法5获得任何东西,只能看起来效率很低–除非编译器能够再次优化向量。
std :: copy是您要寻找的。
由于只能编辑自己的答案,因此我将根据问题的其他答案做出一个综合答案。感谢所有回答的人。
使用std :: copy,它仍然在后台进行迭代,但是您不必键入代码。
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。这可能最适合基本数据类型(即int),但不适用于结构或类的更复杂数组。
vector<int> x(size);
memcpy(&x[0], source, size*sizeof(int));
我说,避免使用memcpy。除非确实需要,否则没有理由搞乱指针操作。另外,它仅适用于POD类型(如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 :-)
myints
?
另一个答案是,由于该人说“我不知道我的函数将被调用多少次”,因此您可以使用向量插入方法,将值数组附加到向量的末尾:
vector<int> x;
void AddValues(int* values, size_t size)
{
x.insert(x.end(), values, values+size);
}
我喜欢这种方式,因为向量的实现应该能够优化,以最佳方式根据迭代器类型和类型本身插入值。您在回应stl的实现。
如果您需要保证最快的速度,并且知道您的类型是POD类型,那么我建议在Thomas的答案中使用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));
}
除了上面介绍的方法外,您还需要确保使用std :: Vector.reserve(),std :: Vector.resize()或将向量构造为适当大小,以确保向量中包含足够的元素它可以保存您的数据。如果没有,您将破坏内存。std :: copy()或memcpy()都是如此。
这就是使用vector.push_back()的原因,您不能写出向量的结尾。
假设您知道向量中的项有多大:
std::vector<int> myArray;
myArray.resize (item_count, 0);
memcpy (&myArray.front(), source, item_count * sizeof(int));