emplace_back() does not behave as expected

*爱你&永不变心* 提交于 2019-12-18 05:28:30

问题


I wrote a simple program to play around with in-place creation of objects inside standard library containers. This is what I wrote:

#include <vector>
#include <iostream>

class AB
{
public:
   explicit AB(int n);
   AB(const AB& other) = delete;
   AB(AB&& other);
   AB& operator=(const AB& other) = delete;
   AB& operator=(AB&& other) = default;
private:
   int i;
};

AB::AB(int n): i( n )
{
   std::cout << "Object created." << std::endl;
};

AB::AB(AB&& other): i( std::move(other.i) )
{
   std::cout << "Object moved." << std::endl;
};

int main()
{
   std::vector< AB > v;
   v.emplace_back(1);
   v.emplace_back(2);
   v.emplace_back(3);
};

I compiled it with g++ (version 4.8.2). After running the output, I got:

Object created.
Object created.
Object moved.
Object created.
Object moved.
Object moved.

But I expected something like this:

Object created.
Object created.
Object created.

I thought the whole point of emplacement was to get rid of the movement constructor calls. Are there any requirements in class AB that are not met?

Thanks for your help.


回答1:


The problem is that your vector is being resized as you add more elements, resulting in extra moves. If you reserve enough capacity at the start, you get the expected result:

   std::vector< AB > v;
   v.reserve(3);
   v.emplace_back(1);
   v.emplace_back(2);
   v.emplace_back(3);

gives

Object created.
Object created.
Object created.

On gcc 4.8.2. Note that you can track the vector's growth in your original code by looking at v.capacity().




回答2:


The point of emplacement is to get rid of the COPY constructor calls. It's probably moving objects around due to resizing the vector when it's full. Moving an object is fine. Copying an object is expensive.



来源:https://stackoverflow.com/questions/23948442/emplace-back-does-not-behave-as-expected

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!