Sha*_*baz 9 c++ language-lawyer c++11
简而言之,我有以下代码:
float x = cond ? 0 : x_option;
Run Code Online (Sandbox Code Playgroud)
where x_option是a template<float>,它有一个operator float()(没有其他自动转换操作符.注意转换后表达式的类型:
bool ? int : float;
Run Code Online (Sandbox Code Playgroud)
我希望这个表达式的结果是float:
C11:
如果第二个和第三个操作数都具有算术类型,那么通常的算术转换确定的结果类型是应用于这两个操作数的结果类型.
所以它遵循相同的规则float + int.
C++ 11:
第二和第三个操作数具有算术或枚举类型; 执行通常的算术转换以使它们成为公共类型,结果是该类型.
同样的规则.
但是,clang和cl.exe都会vcvttss2si在导致评估第3个参数的路径中生成一条指令,即它们决定结果bool ? int : float是a int,而不是float!
为了公平起见,C++ 11有一个我引述前,应申请,并要诚实一些规则,这些规则不是最容易理解的,虽然从我可以做的话,转换int应该是不可能的:
C++ 11:
否则,如果第二个和第三个操作数具有不同的类型并且具有(可能是cv限定的)类类型,或者两者都是相同值类别的glvalues和除cv-qualification之外的相同类型,则尝试转换每个那些操作数与另一种操作数的关系.确定类型T1的操作数表达式E1是否可以转换为匹配类型T2的操作数表达式E2的过程定义如下:
- 如果E2是左值:如果E1可以被隐式转换(第4节)到类型"左值引用T2",则E1可以被转换为匹配E2,受制于转换中引用必须直接绑定的约束(8.5. 3)到左值.
- 如果E2是x值:如果E1可以隐式转换为"rvalue reference to T2"类型,则E1可以转换为匹配E2,受限于引用必须直接绑定.
- 如果E2是一个右值,或者上面的转换都不能完成,并且至少有一个操作数具有(可能是cv-qualified)类类型:
如果E1和E2具有类类型,并且底层类类型相同或者一个是另一个类的基类:如果T2的类与类的类型相同,则可以转换为E1,或者基类类, T1的类别和T2的cv资格是与cv资格相同的cv资格或更高的cv资格.如果应用转换,则通过从E1复制初始化T2类型的临时值并将该临时值用作转换后的操作数,将E1更改为类型T2的prvalue.
否则(即,如果E1或E2具有非类型类型,或者如果它们都具有类类型但基础类不是相同或者是另一个类的基类):如果E1可以是E1,则可以将E1转换为匹配E2如果E2被转换为prvalue(或者它具有的类型,如果E2是prvalue),则隐式转换为表达式E2将具有的类型.
使用该过程,确定是否可以转换第二操作数以匹配第三操作数,以及是否可以转换第三操作数以匹配第二操作数.如果两者都可以转换,或者一个可以转换,但转换不明确,则程序格式不正确.
根据我在上面的理解,这属于第三种情况的第二种情况(最后一个项目符号点的最后一个要点),因此E1(类型int)应该转换为E2(float)的类型.该标准后来表示,如果转换可以双向完成,那么该程序就是格式错误.
这里的裁决是什么?我处于未定义的行为领域吗?或者是标准规定我所看到的转换?
T.C*_*.C. 10
bool ? int : float 是一个浮动.
bool ? int : some_type_convertible_to_float不是:第三个操作数可以转换为int(先转换为float后转int); 的int(可能)不能转换到some_type_convertible_to_float.所以根据你引用的规则,你会得到一个int.