kee*_*lar 6 c++ lvalue rvalue-reference move-semantics c++11
如果我有一个struct我没有提供任何副本和移动构造函数:
struct MyStruct {
MyStruct() { // this is the only function
...
}
...
};
Run Code Online (Sandbox Code Playgroud)
那么如果我做以下事情:
std::vector<MyStruct> vec;
...
vec.push_back(MyStruct());
Run Code Online (Sandbox Code Playgroud)
而不是使用std::move()如下:
vec.push_back(std::move(MyStruct()));
Run Code Online (Sandbox Code Playgroud)
c ++ 11会巧妙地为我的临时变量做些什么吗?或者,我怎样才能确定它是移动而不是副本?
dus*_*yle 10
在C++ 11中,std::vector::push_back如果传递了一个rvalue(并且该类型存在移动构造函数),它将使用移动构造函数,但是你也应该考虑std::vector::emplace_back在这种情况下使用; std::vector::emplace_back将构造对象而不是移动它.
c ++ 11会巧妙地为我的临时变量做些什么吗?或者,我怎样才能确定它是移动而不是副本?
这取决于.这个
vec.push_back(MyStruct());
Run Code Online (Sandbox Code Playgroud)
将绑定到
std::vector<MyStruct>::push_back(MyStruct&&);
Run Code Online (Sandbox Code Playgroud)
但是,传递的右值是否被移动或复制完全取决于是否MyStruct具有移动复制构造函数(同样用于移动赋值).
如果你打电话,它将完全没有区别
vec.push_back(std::move(MyStruct()));
Run Code Online (Sandbox Code Playgroud)
因为MyStruct()已经是右值了.
所以它真的取决于细节MyStruct.你的问题中根本没有足够的信息来知道你的班级是否有移动构造函数.
这些是类具有隐式生成的移动构造函数必须满足的条件:
当然,如果不满足以下任何条件,您可以随时提供自己的条件:
MyStruct(MyStruct&&) = default;
Run Code Online (Sandbox Code Playgroud)
因为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;
}
Run Code Online (Sandbox Code Playgroud)
澄清一下:我没有提到任何有关移动构造函数的内容,因为可以显式删除移动构造函数,但仍然T &&会调用它。
例如(演示):
#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;
}
Run Code Online (Sandbox Code Playgroud)
正如我之前所说,这是因为它是一个右值......
| 归档时间: |
|
| 查看次数: |
1197 次 |
| 最近记录: |