以下涉及自动返回类型的两个声明是否相同?如果是这样,为什么?

时间:2018-12-20 04:06:47

标签: c++ c++11 c++14

我很困惑,为什么我正在读的书说以下两个声明具有相同的作用:

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的类型。这两个声明如何具有相同的作用?

这是我读过的文章:

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:7)

  

在第二个声明中,返回类型为a的类型。

您基于这个假设?我认为这是造成混乱的原因。三元表达式(或任何表达式)的评估静态类型不依赖于对操作数的 values 的任何语义分析,仅依赖于操作数的 types 。这三个表达式中所有三个三元操作数的类型都相同,因此推导的类型也相同。

换句话说,条件操作数为true的事实,在运行时 会导致表达式的计算结果为a,这与以下内容完全无关静态类型分析和推论。

答案 1 :(得分:6)

就像段落中所说的那样,max(a, b)的类型是ab的{​​{3}},因为条件运算符(E1 ? E2 : E3)返回公共类型第二和第三操作数。

答案 2 :(得分:6)

他们没有,但是出于不同的原因。

表达式的类型是静态构造。它不依赖于其操作数的值。如果表达式有效,则b < a ? a : btrue ? a : bfalse ? a : b都具有相同的类型,这取决于ab的类型以及一组复杂的规则在标准中占据约1.5页。

它们确实具有不同的SFINAE效果。如果传递实际上不支持<比较的一对参数,则第一个声明将自身从重载解析中移除,而第二个声明将愉快地接受参数,然后在函数体为时触发硬错误。实例化。仅当您有一个不同的max重载可以接受这些参数,或者您的代码检查调用max的表达式的有效性时,这才真正重要。