简体   繁体   English

emplace_back没有创建就地对象

[英]emplace_back is not creating inplace object

    #include <iostream>
    #include<vector>
    using namespace std;

    class test{
        public:
        test(){
        cout<<"constructor called"<<endl;
    }
     test(const test& obj){
      cout<<"copy constructor called"<<endl;
     }
     test(test&& obj){
      cout<<"Move constructor called"<<endl;
    }     
    };
  int main()
  {
      vector<test> vec;
      vec.emplace_back(test());

      return 0;
  }

When i run above program I expected emplace_back to create object in vector in place.Thus "constructor called" should have been output since emplace_back would avoid creating temporary object. 当我在上述程序上运行时,我期望emplace_back可以在矢量中原地创建对象。由于emplace_back可以避免创建临时对象,因此应该已经输出了“构造函数调用”。

But the output is: 但是输出是:

constructor called
Move constructor called

Here, temporary object is created just like push_back. 在这里,临时对象的创建就像push_back一样。 Please explain. 请解释。

emplace_back doesn't construct temporaries, but you constructed a temporary object explicitly by test() , then the new element is added to the vector from the temporary by the move constructor. emplace_back不会构造临时对象,但是您通过test()显式构造了一个临时对象,然后通过move构造函数将新元素从该临时对象添加到vector

You can just 你可以

vec.emplace_back();

With emplace_back(test()) you already created an object outside of emplace_back and it has a move constructor so it is move-constructed. 使用emplace_back(test())您已经在emplace_back之外创建了一个对象,并且该对象具有move构造函数,因此可以移动构造。 So you should call it without any argument for this case. 因此,在这种情况下,应无任何参数地调用它。 Then you will not see any copy/move constructor calls. 然后,您将看不到任何复制/移动构造函数调用。

vec.emplace_back(); // Will create a test object with constructor `test()` internally

To further understand, if your test class have more constructors, you can give emplace_back with those constructors. 为了进一步理解,如果您的test类具有更多构造函数,则可以为这些构造函数提供emplace_back For example, 例如,

class test {
  ...
  test(int a, int b);
  test(const char* c);
};

And you can do this. 您可以做到这一点。

vec.emplace_back(1, 2);
vec.emplace_back("abcd");

This does not create redundant object which is cannot be done with push_back . 这不会创建使用push_back无法完成的冗余对象。

With emplace_back , the method already knows what class type that you're adding to your vector (you name it when initialising the vector), so the input arguments for emplace_back is only the arguments for the constructor that you want to call (typically you want to avoid the copy constructor, whose argument is an object of the same class): 使用emplace_back ,该方法已经知道要添加到向量中的类类型(在初始化向量时将其命名),因此emplace_back的输入参数是您要调用的构造函数的参数 (通常需要避免其参数是相同类的对象的复制构造函数):

struct A
{
    A (int a, int b, int c)
    {
    // do something
    }

    A (const A & other)
    {
    //do something else
    }
};

std::vector<A> array;

array . emplace_back (1, 2, 3);
// the above finds the constructor with these input arguments
// makes the new object within the vector - no copy

A obj (4, 5, 6);

array . emplace_back ( obj );
// the above looks for the constructor with this object (A)
// it finds a constructor (the copy constructor) and copies

array . emplace_back ( A (1,2,3) );
// the above first processes the inner part: making a new A object
// then searches for a constructor with that argument (an object A)
// in this case that's the copy constructor

In your case you were wanting to call a constructor with no arguments. 在您的情况下,您想调用不带参数的构造函数。 This is why you want to use emplace_back() with no arguments to use this vector method correctly. 这就是为什么要使用不带参数的emplace_back()来正确使用此向量方法的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM