tldr;代码格式良好。条件表达式将具有类型int
和值2
。这是一个MSVC错误。
从[expr.cond]:
否则,如果所述第二和第三操作数具有不同的类型和或者具有(可能CV修饰)类型,或[...],试图从这些操作数中的每一个到另一个操作数的类型形成隐式转换序列(13.3.3.1)。 [...]尝试形成从T1
类型的操作数表达式E1
到与T2
的T2
类型相关的目标类型的隐式转换序列,如下所示:
- 如果E2是
- 如果E2是一个xvalue,
- 如果E2是一个prvalue,或者如果上面的转换序列都不能形成,并且至少有一个操作数具有(可能CV修饰)类类型:
- 如果T1和T2是相同的类类型(IG或非(NOR)CV-资格),或一个是基类的其他, 和T2是至少为CV-限定为T1时,目标类型为T2,
- 否则,目标类型为在应用左值到右值(4.1), 数组到指针(4.2)和函数到指针(4.3)标准转换之后,E2将具有的类型。
因此,我们试图形成一个从std::integral_constant<int, 1>
类型到std::integral_constant<int, 2>
类型的隐式转换序列。这不可行。隐式转换序列在相反方向也不可行。这些类型根本不可互换。
因此,我们继续:
如果不能形成转换 序列,操作数保持不变并如下所述 进行进一步检查。 [...]
如果第二和第三运算数是相同的值的类别和glvalues具有相同的类型,[...]
否则,结果是一个prvalue。如果第二个和第三个操作数不具有相同的类型,并且 具有(可能是cv限定的)类类型,那么使用重载决策来确定应用于操作数(13.3.1.2)的转换(如果有的话)为 , 13.6)。如果重载解决失败,则该程序不合格。
好的,我们可以执行什么重载分辨率?从[over.match.oper]:
如果一个操作数的一个类型,它是一个类或一个枚举,用户定义的函数运算符可以声明实现该操作员或一个用户定义的转换可以有必要将操作数转换为 适合内置操作员的类型。
凡建宏在[over.built]指定为:
对于每一对促进算术类型L和R的,存在形式的候选操作员功能
LR operator?:(bool, L , R);
其中LR是类型L和R之间通常算术转换的结果。
其中一个内置函数将是int operator?:(bool, int, int)
。由于std::integral_constant<int, V>
确实有operator int()
,因此这两个参数都是可行的转换。
我们继续在[expr.cond]:
否则,由此确定的转换被应用,并且将转换后的操作数,以代替原始操作数用于本节的其余部分。
在第二个和第三个操作数上执行左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)的标准转换 。在这些转换之后,下列之一应为:
- 第二个和第三个操作数具有相同的类型;结果是该类型的,并且使用所选操作数初始化结果对象。
在这一点上,第二个和第三个操作数做有相同的类型:int
。所以结果对象被初始化为int
,表达式格式良好。
那么,它们都可以隐式转换为'int',我认为这是它们的通用类型。 – user2079303
他们是,但我试图决定是否允许编译器寻找匹配。这是不明确的部分。 –
[相关问题](http://stackoverflow.com/questions/29381171/ternary-operator-of-different-types)? –