【问题标题】:Return type of decltype when applied to ternary(?:) expression应用于 ternary(?:) 表达式时的 decltype 的返回类型
【发布时间】:2015-05-06 18:05:33
【问题描述】:

当我查看代码 sn-p 以寻找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的用法。

据我所知,返回第二个还是第三个操作数是由第一个操作数的值决定的。在这个 sn-p 中,第一个操作数是 true,这意味着表达式的返回值将始终是 declval&lt;T&gt;()。如果这是我认为没有意义的...因此,我尝试了以下测试

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应用于三元表达式的返回结果是什么?

【问题讨论】:

  • 在您的示例代码中,iii 中的值被转换为float 类型,因为三元的结果是“最宽”类型。
  • 我以为即使第二个和第三个操作数不是同一类型,也不会发生隐式转换。因为 (true ? 1 : 2.0) 将返回 1 而不是 1.0。根据@T.C 的精彩解释,我明白了。一样的感谢。

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


【解决方案1】:

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

取而代之的是一套复杂的规则(超过一页的标准,大部分我在this answer中引用)来确定第二个和第三个操作数的“通用类型”是什么,以及条件表达式属于那种类型。 std::common_type 只是利用了核心语言中的现有规则。

【讨论】:

    猜你喜欢
    • 2013-06-18
    • 2011-01-13
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    相关资源
    最近更新 更多