用户定义的隐式转换运算符和重载解析

Posted

技术标签:

【中文标题】用户定义的隐式转换运算符和重载解析【英文标题】:User-defined implicit conversion operator and overload resolution [duplicate] 【发布时间】:2013-04-18 16:41:18 【问题描述】:

今天我遇到了用户定义的隐式转换运算符的有趣行为。

让我们来看看这段代码:

struct Widget 
    Widget(uint64_t) 

    

    Widget(const std::string &) 

    

    operator uint64_t() 
        return static_cast<uint64_t>(123456789UL);
    

    operator std::string() 
        return std::string("Hello");
    
;

可以隐式转换为 uint64_t 或 std::string 的基本结构。

现在,尝试通过 std::cout 打印出一个 Widget 实例:

#include <iostream>

int main() 
    using std::cout;
    Widget w(123456);

    cout << w;

无论出于何种原因,Widget 将始终转换为 uint64_t。起初我希望调用是模棱两可的,并且可以通过标准显式转换来编译:

int main() 
    using std::cout;
    Widget w(123456);

    cout << static_cast<uint64_t>(w);

但由于我现在忽略的原因,选择了运算符 uint64_t。我试图查看 C++ 规范,但找不到任何有用的信息来回答我的问题。

谁能帮我弄清楚编译器对重载解析做了什么?

【问题讨论】:

【参考方案1】:

uint64_t 转换是首选。原因很简单,&lt;&lt; 被重载为strings (basic_strings) 的模板。编译器在重载解析上总是更喜欢精确匹配而不是模板。

【讨论】:

谢谢,我没有意识到 operator @octal en.cppreference.com/w/cpp/string/basic_string/operator_ltltgtgt【参考方案2】:

当然你可以在 C++ 规范中找到它。

§13.3.1/2§13.3.1/3 中阅读重载分辨率

重载分辨率选择要在七个不同的函数中调用的函数 语言中的上下文...

 

首先,候选函数的子集(具有适当数量的参数并满足某些其他条件的函数)是 选择以形成一组可行的功能 (13.3.2)。 然后根据将每个参数与 每个可行函数的对应参数。

 

简而言之,编译器首先列出要使用的候选者,然后尝试找到最合适和更有效的重载。

【讨论】:

以上是关于用户定义的隐式转换运算符和重载解析的主要内容,如果未能解决你的问题,请参考以下文章

使用接口的隐式运算符

由于 Swift 缺少 CGFloat 的隐式转换而造成的混乱

为啥我可以阻止基元而不是用户定义类型的隐式转换?

关系运算符中的隐式转换

C的隐式类型转换

JavaScript数据类型的隐式转换