C ++-最佳追加方式

这个问题已经在这里有了答案:

  • 将向量附加到向量[重复] 4个答案
std::vector<int> a;
std::vector<int> b;
std::vector<int> c;

我想通过将std::moveC++11的元素添加到a来串联这三个向量,这是最好的方法,为什么?


1)使用std::move

a.reserve(a.size() + b.size() + c.size());
a.insert(a.end(), b.begin(), b.end());
a.insert(a.end(), c.begin(), c.end());
b.clear();
c.clear();

2)使用std::move

a.reserve(a.size() + b.size() + c.size());
std::copy(b.begin(), b.end(), std::inserter(a, a.end()));
std::copy(c.begin(), c.end(), std::inserter(a, a.end()));
b.clear();
c.clear();

3)使用std::move(来自C++11):

a.reserve(a.size() + b.size() + c.size());
std::move(b.begin(), b.end(), std::inserter(a, a.end()));
std::move(c.begin(), c.end(), std::inserter(a, a.end()));
b.clear();
c.clear();
vdenotaris asked 2020-08-04T21:11:51Z
4个解决方案
24 votes

我认为,您的第一个解决方案是最好的方法。

std::move设计为添加元素,因此它是最合适的解决方案。

您可以在目标向量上调用std::move来保留一些空间,但是除非将多个向量加在一起,否则可能不会带来很多好处:vector知道要添加多少个元素,您将避免只执行一次std::move调用。

注意:如果这些是更复杂类型的std::move(即自定义类,甚至是vector),则使用std::move可以为您提供很好的性能提升,因为它将避免使用复制构造函数。 但是,对于int的向量,它不会给您带来任何好处。

注意2:值得一提的是,使用std::move将导致您的源vector的内容不可用。

Xaqq answered 2020-08-04T21:12:27Z
19 votes

假设您要复制而不移动,那么这将是最好的方法:

a.reserve(a.size()+b.size()+c.size()); // Reserve space first
a.insert(a.end(),b.begin(),b.end());
a.insert(a.end(),c.begin(),c.end());

如果要移动:

a.reserve(a.size()+b.size()+c.size()); // Reserve space first
a.insert(a.end(),std::make_move_iterator(b.begin()),
         std::make_move_iterator(b.end()));
a.insert(a.end(),std::make_move_iterator(c.begin()),
         std::make_move_iterator(c.end()));
b.swap(std::vector<int>()); // Clear and deallocate space
c.swap(std::vector<int>()); // Clear and deallocate space

更新:您已经对问题进行了数次编辑,使其成为一个移动的目标。 您的第一个选择现在与我的第一个建议非常相似。

更新2:从C ++ 11开始,您可能不再需要使用“用空向量交换”技巧来清除和释放空间,具体取决于您的库的vector的实现。下面的内容可以更直观地完成此工作。 :

// Empty the vectors of objects
b.clear(); 
c.clear();

// Deallocate the memory allocated by the vectors 
// Note: Unlike the swap trick, this is non-binding and any space reduction
//       depends on the implementation of std::vector
b.shrink_to_fit();
c.shrink_to_fit();
Michael Goldshteyn answered 2020-08-04T21:13:00Z
1 votes

第一个是最佳选择,因为insert可以找出要添加的元素数量,并在开始复制之前调整向量的大小以适合该向量。 其他的则没有该信息,因此可能会在复制后调整大小,这比开始调整大小或多次调整大小要慢。

但是,正如@michaelgoldshteyn所暗示的那样,由于您要进行两次插入,因此您也可以自己使用最终大小调整数组大小,从而可能节省一次调整大小。

Pete Becker answered 2020-08-04T21:13:25Z
0 votes

如果您确实要在向量a中附加std::vectorstd::vector的数据,则必须进行插入(实际上是1):

a.reserve( a.size() + b.size() + c.size() ); // preallocate memory (see why)
a.insert( a.end(), b.begin(), b.end() );
a.insert( a.end(), c.begin(), c.end() );

取决于编译器std::vector(您的2),通常应该一样快。

由于std::vector在内存中必须始终是连续的,因此您不能只是移动(如C ++ 11中所定义),并且如果知道终止大小,则必须保留向量(这将避免向量的不必要的重新分配)。 但是,如果您真的担心性能,那么让这3个std::vector进行访问,并在必须读取它们的数据时对其进行迭代。

Kyle_the_hacker answered 2020-08-04T21:13:54Z
translate from https://stackoverflow.com:/questions/18147400/best-way-to-append-vector-to-vector