如何使foo(std::string{})调用foo(std::string_view)重载以消除编译歧义?
解决重载函数调用歧义问题
问题原因
调用foo(std::string{})时出现编译歧义,是因为编译器存在两条优先级相同的隐式转换路径:
std::string可隐式转换为std::string_view(标准允许的隐式转换)std::string可通过MyClass的转换构造函数,隐式转换为MyClass
编译器无法判定优先选择哪条路径,因此抛出歧义错误。
强制调用void foo(std::string_view v)的方法
方法1:显式转换为
std::string_view
直接将std::string对象显式转换为目标类型,消除歧义:foo(static_cast<std::string_view>(std::string{})); // 或更简洁的写法 foo(std::string_view(std::string{}));方法2:通过字符串数据构造
std::string_view
利用std::string的data()和size()成员直接构造std::string_view:auto s = std::string{}; foo(std::string_view(s.data(), s.size()));方法3:新增精确匹配的重载(推荐)
如果这类调用场景较多,可以新增一个接收std::string参数的重载,转发到std::string_view版本,从根源避免歧义:void foo(const std::string& s) { foo(std::string_view(s)); }后续调用
foo(std::string{})时,编译器会优先匹配这个精确匹配的重载。方法4:禁用
MyClass的隐式转换(按需使用)
若业务逻辑允许,将MyClass的转换构造函数改为显式构造函数,加上explicit关键字:class MyClass { public: explicit MyClass(const std::string& s); // 显式构造函数 };这样编译器不会自动将
std::string隐式转换为MyClass,调用foo(std::string{})时就只会匹配std::string_view版本。注意此方法可能影响其他依赖隐式转换的代码。
内容的提问来源于stack exchange,提问作者Baruch
相关产品推荐
相关产品推荐

