以下是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
是多余的,条件总是解析为第一个操作数是否准确?如果是这样,返回的类型如何满足定义?
答案 0 :(得分:6)
三元条件表达式的类型是两种参数类型的通用类型。因此,三元表达式可以用作常见类型的定义。
请注意decltype
不评估其参数,条件是真还是假是无关紧要的。
答案 1 :(得分:4)
三元运算符的类型不仅仅是编译器知道必须采用的分支类型。如果存在这样的类型,则它是两个分支共有的类型。如果没有这种类型,则编译失败。三元运算符是唯一具有属性的运算符,它将转换为表达式的公共类型,而不是两个值上的表达式的结果。也就是说,三元运算符只是被滥用来获得通用类型。然而,这种情况并不重要。
标准中的相关部分是5.16 [expr.cond]第3段:
否则,如果第二个和第三个操作数具有不同的类型并且具有(可能是cv限定的)类类型,或者两者都是相同值类别的glvalues和除cv-qualification之外的相同类型,则尝试将每个操作数转换为另一个操作数的类型。
该段落之后是如何提供常见类型的规则。 否则指的是第二个或第三个表达式是 throw-expression 或者第二个或第三个表达式中的一个或两个具有类型void
的情况
答案 2 :(得分:2)
其他解释是正确的,但我认为一个简单的示例程序将显示三元运算符如何更好地工作:
int main() {
std::cout << demangle(typeid(true ? 1 : 3.14).name()) << std::endl;
}
liveworkspace上的上述程序打印double
,但第二个操作数是int
。这是因为三元运算符的结果是第二个和第三个操作数之间的公共类型(在这种情况下是int
和double
)。当您将decltype
应用于此运算符时,这就是您所获得的。