我很困惑,为什么我正在读的书说以下两个声明具有相同的作用:
template<typename T1, typename T2> auto max (T1 a, T2 b) -> decltype(b<a?a:b);
template<typename T1, typename T2> auto max (T1 a, T2 b) -> decltype(true?a:b);
在第一个声明中,返回类型max(a, b)
可以是a
的类型,也可以是b
的类型。在第二个声明中,返回类型是a
的类型。这两个声明如何具有相同的作用?
这是我读过的文章:
答案 0 :(得分:7)
在第二个声明中,返回类型为
a
的类型。
您基于这个假设?我认为这是造成混乱的原因。三元表达式(或任何表达式)的评估静态类型不依赖于对操作数的 values 的任何语义分析,仅依赖于操作数的 types 。这三个表达式中所有三个三元操作数的类型都相同,因此推导的类型也相同。
换句话说,条件操作数为true
的事实,在运行时 会导致表达式的计算结果为a
,这与以下内容完全无关静态类型分析和推论。
答案 1 :(得分:6)
就像段落中所说的那样,max(a, b)
的类型是a
和b
的{{3}},因为条件运算符(E1 ? E2 : E3
)返回公共类型第二和第三操作数。
答案 2 :(得分:6)
他们没有,但是出于不同的原因。
表达式的类型是静态构造。它不依赖于其操作数的值。如果表达式有效,则b < a ? a : b
,true ? a : b
和false ? a : b
都具有相同的类型,这取决于a
和b
的类型以及一组复杂的规则在标准中占据约1.5页。
它们确实具有不同的SFINAE效果。如果传递实际上不支持<
比较的一对参数,则第一个声明将自身从重载解析中移除,而第二个声明将愉快地接受参数,然后在函数体为时触发硬错误。实例化。仅当您有一个不同的max
重载可以接受这些参数,或者您的代码检查调用max
的表达式的有效性时,这才真正重要。