为何std::move可作用于常量对象?下述C++代码为何合法?
为什么这段带const引用和std::move的C++代码合法?
嘿,这个问题戳中了很多人对std::move的误解点,我来一步步给你理清楚:
首先,得搞懂std::move到底在做什么
std::move不是真的移动对象,它只是一个类型转换工具:
- 如果你给它一个非const的左值,它会把这个左值转换成
T&&(非const右值引用) - 但如果你的输入是
const T&(就像代码里的s1),它转换后的结果是const T&&——也就是const的右值引用
然后看std::string的构造函数匹配逻辑
std::string的移动构造函数签名是:
string(string&& other);
这个构造函数只接受非const的右值引用,所以当我们传递const string&&的时候,它是匹配不上的。这时候编译器会去找能匹配的构造函数,而std::string的拷贝构造函数:
string(const string& other);
const string&&是可以隐式转换成const string&的(毕竟所有const右值都能绑定到const左值引用上),所以最终编译器会调用拷贝构造函数,而不是移动构造函数。
为什么不会触发const对象被修改的错误?
因为根本没执行移动操作!拷贝构造函数只会读取原const对象的内容,创建一个新的副本,完全不会修改原对象的状态,自然不会违反const的限制。所以代码能正常编译运行,不会报错。
验证小技巧(可选)
如果你想确认这一点,可以给std::string的构造函数加日志(或者用编译器的调试功能),你会发现代码里的s(std::move(s1))实际上调用的是拷贝构造,而不是移动构造。
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

