如何让C++优先将char*转换为std::string_view而非bool?
问题根因
该现象由C++重载决议的优先级规则导致:
- 传入的字符串字面量
"foo"属于const char[4]类型,它可以先隐式退化为const char*指针,再通过标准转换转为bool类型,整个转换链路属于「标准转换序列」 - 而
const char*转std::string_view需要调用std::string_view的构造函数,属于「用户定义转换序列」 - C++标准规定重载决议时标准转换序列的优先级高于用户定义转换序列,因此编译器优先选择了
print(bool)的重载。
可行解决方案
方案1:新增const char*重载(全版本兼容,改动最小)
在类中新增接收const char*参数的print重载,主动转发到std::string_view版本即可。const char*是字符串字面量退化后的精准匹配类型,优先级远高于转bool的标准转换:
class C { public: void print(std::string_view v) { std::cout << "string_view: " << v << std::endl; } // 新增const char*重载,拦截字符串指针的匹配 void print(const char* s) { print(std::string_view{s}); } void print(bool b) { std::cout << "bool: " << b << std::endl; } };
方案2:调用时显式指定std::string_view类型(无需修改类定义)
如果不方便修改类的代码,调用时主动做类型转换即可:
// 直接显式构造 c.print(std::string_view{"foo"}); // C++14及以上可以用标准库的字符串字面量后缀,写法更简洁 using namespace std::literals; c.print("foo"sv);
方案3:C++20以上版本可约束bool重载仅接收bool类型入参
如果使用C++20及以上版本,可以通过std::same_as概念限制bool重载只能匹配严格的bool类型入参,禁止其他类型隐式转换匹配:
#include <concepts> class C { public: void print(std::string_view v) { std::cout << "string_view: " << v << std::endl; } // 仅接收严格bool类型的入参,排除指针等类型的隐式转换匹配 void print(std::same_as<bool> auto b) { std::cout << "bool: " << b << std::endl; } };
内容的提问来源于stack exchange,提问作者Thomas Johnson
相关产品推荐
相关产品推荐

