简体   繁体   English

多个隐式转换运算符

[英]Multiple implicit conversion operators

Consider the following C++ code: 考虑以下C ++代码:

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

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

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

GCC compiles it successfully. GCC成功编译。 Clang gives an error: Clang给出了一个错误:

error: conditional expression is ambiguous; 错误:条件表达式不明确; 'X' and 'Y' can be converted to several common types 'X'和'Y'可以转换为几种常见类型

MSVC also gives an error: MSVC也会出错:

error C2446: ':': no conversion from 'Y' to 'X' 错误C2446:':':没有从'Y'到'X'的转换

note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 注意:没有可用于执行此转换的用户定义转换运算符,或者无法调用运算符

Which compiler is correct here, and what is the relevant part of the C++ Standard in this case? 这里的编译器是正确的,在这种情况下C ++标准的相关部分是什么? My guess is [over.match.oper] is applicable, but so far I was not able to figure out the expected behavior from it. 我的猜测是[over.match.oper]是适用的,但到目前为止我无法弄清楚它的预期行为。

Update: if we change both operator int() to convert to some other type, eg operator bool() , then GCC gives an error as well. 更新:如果我们改变operator int()以转换为其他类型,例如operator bool() ,那么GCC也会给出错误。 Maybe there is some special rule about int type? 也许有一些关于int类型的特殊规则?

I think it's stated here, [expr.cond]/6 : 我想这里说的是[expr.cond] / 6

(emphasis mine) (强调我的)

Otherwise, the result is a prvalue. 否则,结果是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]). 如果第二个和第三个操作数不具有相同的类型,并且具有(可能是cv限定的)类类型, 则使用重载决策来确定要应用于操作数的转换(如果有)([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. 否则,应用如此确定的转换,并使用转换的操作数代替本子条款其余部分的原始操作数。

That means, given X and Y , which are two different types, overload solution will try to determine any conversion which could be applied. 这意味着,给定XY ,它们是两种不同的类型,过载解决方案将尝试确定可以应用的任何转换。 Overload solution fails because both X and Y could be converted to multiple types. 重载解决方案失败,因为XY都可以转换为多种类型。 The program is ill-formed; 该计划格式不正确; Clang is correct. 铿锵是对的。

Note that overload resolution fails because there're multiple conversions for X and Y then the conversion can't be determined. 请注意,重载决策失败,因为XY有多次转换,因此无法确定转换。 That means even they might have common type after appropriate conversion is performed, the following code is still ill-formed. 这意味着即使在执行适当的转换后它们可能具有共同类型,以下代码仍然是不正确的。

struct X {
    operator int();
};

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

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

Error message from clang : 来自clang的错误消息:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM