【问题标题】:Overloaded function and multiple conversion operators ambiguity in C++, compilers disagreeC ++中重载函数和多个转换运算符的歧义,编译器不同意
【发布时间】:2021-12-20 12:34:07
【问题描述】:

在以下程序结构S 中提供了两个转换运算符:doublelong long int。然后将S 类型的对象传递给函数f,为floatdouble 重载:

struct S {
    operator double() { return 3; }
    operator long long int() { return 4; }
};

void f( double ) {}
void f( float ) {}

int main() {
    S s;
    f( s );
}

MSVC 编译器接受程序正常,选择f( double ) 重载。然而,GCC 和 Clang 在调用 f 时都看到了歧义,演示:https://gcc.godbolt.org/z/5csd5dfYz

似乎MSVC就在这里,因为转换: operator long long int() -> f( float ) 不是促销。错了吗?

有一个类似的问题Overload resolution with multiple functions and multiple conversion operators,但是里面有一个提升案例,现在所有编译器都同意了,不像这个问题的案例。

【问题讨论】:

  • 即使将 long long int 转换运算符更改为 bool 也无济于事,这似乎很不幸,直觉上没有人会认为 bool->float 是个好主意。

标签: c++ language-lawyer overloading overload-resolution conversion-operator


【解决方案1】:

GCC 和 Clang 是正确的。隐式转换序列(用户定义的转换序列)是无法区分的。

[over.ics.rank]/3:

(强调我的)

两个相同形式的隐式转换序列是 不可区分的转换序列,除非以下之一 规则适用:

...

(3.3) 自定义转换序列U1是更好的转换序列 比另一个用户定义的转换序列 U2 如果它们包含 相同的用户定义的转换函数或构造函数,或者他们 在聚合初始化中初始化同一个类 情况下 U1 的第二个标准转换序列优于 U2的第二个标准转换序列。

用户定义的转换序列涉及两个不同的用户定义的转换函数(operator double()operator long long int()),所以编译器不能选择一个;不考虑第二个标准转换序列。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2020-06-12
    • 2021-05-02
    • 2020-12-16
    • 2014-07-28
    • 1970-01-01
    相关资源
    最近更新 更多