【问题标题】: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++ 规范,但找不到任何有用的信息来回答我的问题。

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

【问题讨论】:

    标签: c++


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

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

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

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

     

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

     

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 2017-09-18
      • 2016-09-01
      • 2014-08-18
      • 1970-01-01
      相关资源
      最近更新 更多