c++ - 多个隐式转换运算符

标签 c++ language-lawyer clang++ conditional-operator conversion-operator

考虑以下 C++ 代码:

struct X {
    operator int();
    operator char();
};

struct Y {
    operator int();
    operator char();
};

void f(bool z) { 
    z ? X() : Y(); 
}

GCC 编译成功。 Clang报错:

error: conditional expression is ambiguous; 'X' and 'Y' can be converted to several common types

MSVC 也报错:

error C2446: ':': no conversion from 'Y' to 'X'

note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

这里哪个编译器是正确的,在这种情况下,C++ 标准的相关部分是什么?我的猜测是 [over.match.oper] 是适用的,但到目前为止我无法从中找出预期的行为。

更新:如果我们同时更改 operator int() 以转换为其他类型,例如operator bool(),然后 GCC 也报错。也许有一些关于 int 类型的特殊规则?

最佳答案

我认为这里已经说明了,[expr.cond]/6 :

(强调我的)

Otherwise, the result is a prvalue. If the second and third operands do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be applied to the operands ([over.match.oper], [over.built]). If the overload resolution fails, the program is ill-formed. Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this subclause.

这意味着,给定 XY 这两种不同的类型,重载解决方案将尝试确定可以应用的任何转换。重载解决方案失败,因为 XY 都可以转换为多种类型。该程序格式错误; Clang 是正确的。

请注意,重载解析失败是因为 XY 有多个转换,因此无法确定转换。这意味着即使在执行适当的转换后它们可能具有共同的类型,以下代码仍然是错误的。

struct X {
    operator int();
};

struct Y {
    operator int();
    operator char();
};

void f(bool z) { 
    z ? X() : Y(); 
}

来自 clang 的错误消息:

prog.cc:11:7: error: conditional expression is ambiguous; 'X' and 'Y' can be converted to several common types
    z ? X() : Y(); 
      ^ ~~~   ~~~

关于c++ - 多个隐式转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51624928/

相关文章:

rust - Rust 的确切自动解引用规则是什么?

c++ - 在析构函数调用未定义行为后访问内存吗?

c++ - 尝试在 Linux 上使用 Clang++ 编译 c++11 正则表达式教程时出错

c - 如何生成如下所示的输出?

c++ - C/C++ 中 isspace 的声明不一致?

c++ - ITypeLib : GetLibAttr and ReleaseTLibAttr

C++20 契约和未使用的变量

gcc - 为什么 LLVM 项目使用 GCC Headers

c++ - 如何强制 std::weak_ordering

c++ - C++(和 C)类型转换期间明显不一致