为何std::move作用于const对象时调用const reference而非rvalue reference?
为什么std::move(const对象)会调用const引用而非右值引用?
先看你的代码:
#include <iostream> void bar(std::string& s) { std::cout << "ref" << std::endl;} void bar(const std::string& s) { std::cout << "const ref" << std::endl;} void bar(std::string&& s) { std::cout << "rvalue ref" << std::endl;} int main (int argc, char *argv[]) { const std::string text{"text"}; bar(text); bar(std::string{"text"}); bar("text"); std::string text1{"text"}; bar(text1); bar(std::move(text)); return 0; }
核心问题拆解:
std::move对const对象的实际效果
std::move只是把传入对象转换为右值类型,但会保留原对象的const属性。你传入的text是const std::string,所以std::move(text)得到的是const std::string&&(const右值引用),而非你以为的std::string&&(非const右值引用)。重载函数的匹配规则
你的三个bar重载里:
bar(std::string&):只能绑定非const左值,直接被排除;bar(std::string&&):只能绑定非const的右值,const std::string&&无法匹配这个重载(非const引用不能绑定到const对象,哪怕它是右值);bar(const std::string&):这个重载的const左值引用可以绑定所有类型的字符串——包括const左值、非const左值、const右值、非const右值,所以最终只能匹配这个版本。
- 优先级补充说明
如果存在bar(const std::string&& s)这个重载,它会比bar(const std::string&)优先级更高,因为编译器会优先选择最精确的匹配。但你当前没有定义这个重载,所以只能退而求其次选择const左值引用。
验证方法
如果去掉text的const修饰,std::move(text)会得到非const右值,此时就会调用bar(std::string&&),输出"rvalue ref",和你最初的预期一致。
内容的提问来源于stack exchange,提问作者Chp Cht
相关产品推荐
相关产品推荐

