所以我是新手移动语义,我正在测试以下代码.我的理解是rvalue将调用移动构造函数,我期望A("123")将导致移动构造函数被调用.但是当我运行它时,会调用复制构造函数.
#include <string>
#include <iostream>
#include <utility>
class A
{
std::string s;
public:
A(const std::string& in) : s(in) { std::cout << "ctor!\n";}
A(const A& o) : s(o.s) { std::cout << "move failed!\n"; }
A(A&& o) noexcept : s(std::move(o.s)) { }
};
class B
{
A d_a;
public:
B(const A& a) :d_a(a)
{}
};
int main()
{
std::cout << "Trying to move A\n";
B b(A("123")); // move-constructs from rvalue temporary
}
Run Code Online (Sandbox Code Playgroud)
问题是以下构造函数B:
B(const A& a) :d_a(a) {}
Run Code Online (Sandbox Code Playgroud)
函数参数const A&是一个const限定的左值引用,您无法将其转换为右值.您需要将构造函数更改为(或添加第二个)
B(A&& a) : d_a(std::move(a)) {}
Run Code Online (Sandbox Code Playgroud)
作为旁注,如果您只是将它们定义为,则可以免费获得示例中类型的正确移动语义
struct A {
std::string s;
};
struct B {
A d_a;
};
Run Code Online (Sandbox Code Playgroud)
使用客户端代码
B b{A{"123"}};
Run Code Online (Sandbox Code Playgroud)
我明白,你想不依赖于编译器生成的特殊成员函数调查布展施工的缘故,我只是不想忽略此快捷方式,因为这是一个设置应力求:让副本您的类的移动语义由其数据成员自动组装.