应用于三元(?:)表达式时返回decltype的类型

时间:2015-05-06 18:05:34

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

当我查看可能实现std::common_type

的代码段时
template <class ...T> struct common_type;

template <class T>
struct common_type<T> {
    typedef decay_t<T> type;
};

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

template <class T, class U, class... V>
struct common_type<T, U, V...> {
    typedef common_type_t<common_type_t<T, U>, V...> type;
};

如何获得两个模板参数的通用类型的部分让我感到困惑。它是使用decltype的三元运算符。

众所周知,是否返回第二个或第三个操作数取决于第一个操作数的值。在此代码段中,第一个操作数为 true ,这意味着表达式的返回值始终为 declval<T>() 。如果这是我认为没有意义的......因此,我尝试了以下测试

int iii = 2;
float fff = 3.3;
std::cout << typeid(decltype(false? std::move(iii):std::move(fff))).name() << std::endl;
std::cout << typeid(decltype(std::move(iii))).name() << std::endl;
std::cout << typeid(decltype(false ? iii : fff)).name() << std::endl;
std::cout << typeid(decltype(true ? iii : fff)).name() << std::endl;

// [02:23:37][ryu@C++_test]$ g++ -std=c++14 -g common_type.cpp
// output 
// f
// i
// f
// f

与运行结果相比,结果我应该如下所示

int iii = 2;
float fff = 3.3;
std::cout << typeid(decltype(false ? iii : fff)).name() << std::endl; // should return f;
std::cout << typeid(decltype(true ? iii : fff)).name() << std::endl;  // should return i;

任何人何时可以帮助解释为什么跑步结果不同?

换句话说,当它应用于三元表达式时,decltype的返回结果是什么?

1 个答案:

答案 0 :(得分:4)

表达式的类型是编译时属性。条件表达式中的第一个操作数的值(以及因此选择的分支)通常是运行时事物,因此它可能不会影响表达式&#39; s型。

相反,一组复杂的规则(超过一页标准,我在this answer引用的大部分内容)用于确定&#34;常见类型&#34;第二个和第三个操作数是,并且条件表达式是该类型。 std::common_type仅仅利用核心语言中的现有规则。