3

以下是 的专业之一std::common_type

template <class T, class U>
struct common_type<T, U> {
    typedef decltype(true ? declval<T>() : declval<U>()) type;
};

我的想法是条件语句是不必要的。如果它正在检查true,表达式是否总是会解析为declval<T>()?如果是这样,返回的 typedef 如何证明定义的合理性......

“确定所有类型中的通用类型T...,即所有类型都T...可以隐式转换为的类型。”

有人可以解释条件语句吗?检查true是多余的,并且条件总是会解析到第一个操作数,这是否准确?如果是这样,返回的类型如何满足定义?

4

3 回答 3

6

三元条件表达式的类型两种参数类型的共同类型。因此,三元表达式可以用作通用类型的定义

请注意,decltype它不会评估其参数,并且条件是真还是假是无关紧要的。

于 2013-01-14T22:36:24.383 回答
4

三元运算符的类型不仅仅是编译器知道它必须采用的分支的类型。如果有这样的类型,它就是两个分支共有的类型。如果没有这种类型,则编译失败。三元运算符是唯一具有将其转换为表达式的通用类型而不是两个值的表达式结果的属性的运算符。也就是说,三元运算符只是被滥用来获取通用类型。然而,条件并不重要。

标准中的相关部分是 5.16 [expr.cond] 第 3 段:

否则,如果第二个和第三个操作数具有不同的类型并且具有(可能是 cv 限定的)类类型,或者如果两者都是相同值类别和相同类型(除了 cv 限定)的 glvalue,则尝试转换每个这些操作数的类型到另一个的类型。

段落后面是如何提供通用类型的规则。否则是指第二个或第三个表达式是 throw -expression或第二个或第三个表达式中的一个或两个具有 type 的情况void

于 2013-01-14T22:42:29.910 回答
2

其他解释是正确的,但我认为一个简单的示例程序将展示三元运算符如何更好地工作:

int main() {
    std::cout << demangle(typeid(true ? 1 : 3.14).name()) << std::endl;
}

尽管第二个操作数doubleint. 这是因为三元运算符的结果是第二个和第三个操作数之间的公共类型(在这种情况下是intand double)。当您申请decltype该运营商时,这就是您所得到的。

于 2013-01-14T22:59:02.640 回答