char[]能否转为右值?如何调用右值版本的f1重载函数?
问题分析与解决方法
你的重载定义本身没有语法错误,出现两次调用都触发左值版本的问题,和MSVC在C++17标准下对数组右值引用的特殊处理逻辑有关:
问题原因
std::move(s)返回的确实是char(&&)[4]类型的右值引用,但在MSVC的C++17实现中,非const的数组右值引用重载的匹配优先级低于const左值引用重载,导致std::move(s)被隐式转换为const char(&)[4],从而匹配到左值版本的函数。
触发右值版本的可行方法
有两种可靠的解决途径:
1. 显式构造临时非const数组
直接传递一个临时数组的右值,让编译器精确匹配右值版本重载,示例代码:
f1(static_cast<char(&&)[4]>({'a', 's', 'd', '\0'}));
或者更简洁的写法(注意数组长度必须严格匹配4):
f1( (char[4]){"asd"} );
2. 修改右值重载为const版本
如果你的函数不需要修改数组内容,可以将右值重载的参数改为const char(&&)[4]:
void f1(const char(&&)[4]) { std::cout << "f1 rvalue" << std::endl; }
此时调用f1(std::move(s))会优先匹配这个右值版本——因为const右值引用可以绑定到std::move(s)返回的右值,且匹配优先级高于const左值引用。
操作可行性说明
两种方法均完全可行:第一种适合必须使用非const数组的场景,第二种更简洁通用,只要业务逻辑允许使用const数组即可。另外需要确保代码已包含<utility>头文件,否则std::move可能无法正常工作。
内容的提问来源于stack exchange,提问作者f1msch
相关产品推荐
相关产品推荐

