为什么这可以“按预期”工作?
我的理解是,这不起作用:

template <class T, class U>
auto x(T a, U b) -> decltype(a<b ? a:b) {
    return a > b ? a : b;
}


int main() {
    cout << x<long, double>(1, 2.01) << endl;
    cout << x<long, double>(5, 2.01) << endl;

}

我尝试了其他一些组合,例如:
template <class T, class U>
auto x(T a, U b) -> decltype(a<b ? a:a) {
    return a > b ? a : b;
}

这样,它不会编译错误实际上第二个组合失败
compile time error:  Error C2440 'return': cannot convert from 'U' to 'T &'

这是预期的。我的理解是,第一个函数也应该会因相同的错误而失败,尽管它可以正常工作。

最佳答案

?:运算符的条件是什么都没有关系。结果类型被计算为第二和第三操作数的通用类型。这是?:运算符的通用类型和值类别的计算方式的一部分,有关详细信息,请参见cppreference.com:

如果第二和第三操作数是相同类型的左值,那么结果类型将是该类型的左值。

如果类型是不相关的左值,则有一些更复杂的规则来确定通用类型,但是结果将是prvalue,而不是lvalue。特别是,如果这两种类型是算术类型,例如doublelong,则将usual arithmetic conversions应用于获得通用类型。对于longdouble,常见类型是double。这与如果您进行例如尝试使用+添加两个不同的算术类型,因此命名为通常的算术转换。

因此,如果decltype(a<b ? a:b)a具有相同的类型,则b将是引用类型,否则它将不是引用类型。

这就是函数编译的原因。通用类型始终使两种输入类型都可以转换为通用类型。这也是为什么如果类型相等则函数具有未定义行为的原因,因为decltype提供了引用,因此您将返回对函数参数之一的引用。
decltype(a<b ? a:a)不适用于不同的类型,因为如上所述,aa的常见类型是a类型的引用。如果b具有不同的无关类型,则a > b ? a : b的结果将是一个prvalue,该prvalue无法绑定(bind)到左值引用。

09-04 02:47
查看更多