[英]why does vector.emplace_back call the move-constructor?
struct Object {
Object() { cout << "constructor\n"; }
Object(const Object &) { cout << "copy constructor\n"; }
Object(Object &&) { cout << "move constructor\n"; }
};
int main() {
vector<Object> v;
v.reserve(10);
v.emplace_back(Object{});
}
This gives me the following output: 这给了我以下输出:
constructor 建设者
move constructor 移动构造函数
Why? 为什么? I thought that emplace_back does create the Object in place, so that no copy or move constructors have to be called. 我认为emplace_back确实会在原处创建Object,因此无需调用任何复制或移动构造函数。
From the description: 根据描述:
The element is constructed in-place, ie no copy or move operations are performed. 元素是就地构造的,即不执行复制或移动操作。
EDIT: Ah, okay, it seems that I fundamentally misunderstood emplace_back(). 编辑:啊,好的,看来我从根本上误解了emplace_back()。 You don't have to have the Object as an argument, since it is automatically created in place for you. 您不必将Object作为参数,因为它是为您自动创建的。 You only have to give the arguments for the Object-constructor to emplace_back(). 您只需将Object-constructor的参数提供给emplace_back()。
So, if I had a new constructor like this: 因此,如果我有一个像这样的新构造函数:
Object(int) { cout << "int constructor\n"; }
I would call emplace_back like this: 我会这样称呼emplace_back:
v.emplace_back(42);
instead of this: 代替这个:
v.emplace_back(Object(42));
Makes sense now, thanks a lot! 现在有意义,非常感谢!
EDIT2: I wish I could accept all of your answers! EDIT2:希望我能接受您的所有答复! :-P :-P
emplace_back
forwards its arguments to the constructor of the vector element class, called in-place on the next available position of the vector
. emplace_back
转发它的参数向量元素类的构造函数,称为就地上的下一个可用的位置vector
。
v.emplace_back(Object{});
is sort of equivalent to: 相当于:
{
Object tmp;
v.emplace_back(std::move(tmp));
}
That's why you are getting a regular constructor call followed by a move constructor call. 这就是为什么要得到常规构造函数调用以及移动构造函数调用的原因。 If you want to append a new object with emplace_back
, just call: 如果要使用emplace_back
附加新对象,只需调用:
v.emplace_back();
Just for the sake of completeness, another reason why emplace_back
might call a move constructor is: emplace_back
may cause the vector
to grow, and thus move its initial contents to their new memory location. 仅出于完整性考虑, emplace_back
可能调用move构造函数的另一个原因是: emplace_back
可能导致vector
增长,从而将其初始内容移动到其新的内存位置。 This is not the problem here, because calling reserve
guarantees enough capacity, but generally it's an answer to the question. 这不是这里的问题,因为调用reserve
保证足够的容量,但这通常是问题的答案。
v.emplace_back(Object{});
will call a placement new new (place) Object(Object{})
so a move constructor. 将调用一个新的placement new new (place) Object(Object{})
因此移动构造函数。
Use v.emplace_back();
使用v.emplace_back();
to avoid to call extra object constructor, 为了避免调用额外的对象构造函数,
which will result in new (place) Object;
这将导致new (place) Object;
emplace_back
calls whatever constructor matches the arguments you pass it. emplace_back
调用与您传递的参数匹配的任何构造函数。 In this case you have chosen to pass Object{}
, which matches the Object&&
move constructor. 在这种情况下,您选择传递与Object&&
move构造函数匹配的Object&&
Object{}
。
When the description says, "no move or copy is performed", it means apart from the object construction that you specify. 当描述说“不执行移动或复制”时,表示除指定的对象构造以外。 If that construction happens to be a move or copy then of course it is performed. 如果该构造恰好是移动或复制,那么当然可以执行。
If you want emplace_back
to use the no-args constructor then pass it no arguments: v.emplace_back()
. 如果希望emplace_back
使用no-args构造函数,则不传递任何参数: v.emplace_back()
。
The version you are linking is for passing constructor arguments. 您链接的版本用于传递构造函数参数。 To achieve the desired effect, you could call v.emplace_back();
为了达到预期的效果,可以调用v.emplace_back();
You are calling emplace_back
with an object of the same type that is stored in the vector so you are requesting a copy of that object (Same as Object O(Object{});
). 您正在emplace_back
与向量中存储的相同类型的对象调用emplace_back
,因此您请求该对象的副本(与Object O(Object{});
)。 Since you provide a temporary, the move constructor is invoked instead of the copy constructor. 由于提供的是临时文件,因此将调用move构造函数而不是copy构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.