如果我有一个struct
我没有提供任何副本并移动构造函数:
struct MyStruct {
MyStruct() { // this is the only function
...
}
...
};
然后如果我执行以下操作:
std::vector<MyStruct> vec;
...
vec.push_back(MyStruct());
而不是使用std::move()
,如下所示:
vec.push_back(std::move(MyStruct()));
c ++ 11会巧妙地为我的临时变量做些什么吗?或者,我怎样才能确定它是移动而不是副本?
答案 0 :(得分:10)
在C ++ 11中std::vector::push_back
如果传递rvalue将使用移动构造函数(并且该类型存在移动构造函数),但在这种情况下也应考虑使用std::vector::emplace_back
; std::vector::emplace_back
将构建对象而不是移动它。
答案 1 :(得分:7)
c ++ 11会巧妙地为我的临时变量做些什么吗?或者,我怎样才能确定它是移动而不是副本?
这取决于。此
vec.push_back(MyStruct());
将绑定到
std::vector<MyStruct>::push_back(MyStruct&&);
但是移动或复制的rvalue是否完全取决于MyStruct
是否具有移动复制构造函数(同样用于移动分配)。
如果你打电话
,那绝对没有区别vec.push_back(std::move(MyStruct()));
因为MyStruct()
已经是左值。
所以它真的取决于MyStruct
的细节。你的问题中没有足够的信息来知道你的班级是否有移动构造函数。
这些是类具有隐式生成的移动构造函数必须满足的条件:
当然,如果不满足以下任何条件,您可以随时提供:
MyStruct(MyStruct&&) = default;
答案 2 :(得分:4)
因为MyStruct()
会创建一个左值,所以会调用T &&
重载。
实际上很容易验证(demo):
#include <iostream>
struct A{ int x; };
void foo(A &&x){ std::cout<<"&&" <<std::endl; }
void foo(A &x){ std::cout<<"&" <<std::endl; }
int main() {
foo(A()); // prints &&
A a;
foo(a); // prints &
return 0;
}
澄清一下:我没有提及有关移动构造函数的任何内容,因为可以有一个显式删除的移动构造函数,但仍会调用T &&
。
E.g(demo):
#include <iostream>
struct A{ int x; A() = default; A(const A& ) = default; A(A&&) = delete; };
/* ^
no move ctor */
void foo(A &&x){ std::cout<<"&&" <<std::endl; }
void foo(A &x){ std::cout<<"&" <<std::endl; }
int main() {
foo(A()); //still prints &&
A a;
foo(a);
return 0;
}
正如我之前所说,这是因为它是一个左值......
答案 3 :(得分:1)
是的,它将使用push_back( T&& value ),并移动值。
答案 4 :(得分:1)
如果类型是可移动的,那肯定会是。通常,符合标准的编译器应始终选择移动语义来复制语义(如果有的话)。