【问题标题】:std::common_type implementationstd::common_type 实现
【发布时间】:2012-09-05 21:27:10
【问题描述】:

为了看看它是如何工作的,我在标题 type_traits 中查看了 std::common_type 的 libstdc++ 实现。我不得不承认我真的不明白它是如何工作的。这里是:

/// common_type
template<typename... _Tp>
    struct common_type;

template<typename _Tp>
    struct common_type<_Tp>
    { typedef _Tp type; };

template<typename _Tp, typename _Up>
    struct common_type<_Tp, _Up>
    { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };

template<typename _Tp, typename _Up, typename... _Vp>
    struct common_type<_Tp, _Up, _Vp...>
    {
        typedef typename
        common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
    };

我非常了解第一个、第二个和第四个声明的工作原理。但是,我无法理解第三个声明是如何工作的。有人能解释一下这里使用的机制吗?

【问题讨论】:

    标签: c++ c++11 g++ typetraits


    【解决方案1】:

    首先,std::declval&lt;T&gt;() 产生一个T 类型的右值。尝试对该值执行任何操作都会失败,因此它只能在未评估的上下文中使用。接下来,三元运算符将其类型推断为两个参数共有的最特殊类型(如果没有这样的类型,则失败)。那么,表达式的类型

    true? declval<T0>(): declval<T1>()
    

    T0T1 最专业的常见类型。剩下的就是将这个表达式转换为一个类型并确保它不被评估。 decltype(expr) 就是这样做的。显然,两个参数版本是逻辑的核心:其他版本用于处理极端情况(一个参数)并利用两个参数版本来产生任意类型的通用类型。

    【讨论】:

      【解决方案2】:

      第三个版本使用条件运算符来确定通用类型。它的规则在标准的第 5.16 节中有相当长的描述,所以我不确定是否应该在这里复制它们。

      简单来说就是表达式:

      boolean-expression ? second-operand : third-operand
      

      具有第二个和第三个操作数的“通用类型”(如果存在)。然后使用decltype 说明符将表达式“转换”为类型说明符。

      【讨论】:

      • +1,很好地阅读了magic,包括三元运算符:Conditional Love: FOREACH redux
      • 好吧,我想我终于明白了。因此,它依赖于三元运算符根据其操作数推断其返回类型这一事实。它没有想到这一点。谢谢!
      【解决方案3】:

      长话短说:decltype 使 C++ 编译器为其确定最接近的祖先类型。

      三级运算符具有两个可能表达式的最接近祖先的静态类型。

      例如:

      A 继承自 B

      X 继承自 Y 继承自 B

      <expression> ? <expression with static type A> : <expression with static type X> 
          = <expression with static type B>  // this is how the C++ parser sees it
      

      这就是 C++ 语言的工作原理。 decltype 只是使 typedef 成为该表达式结果的静态类型(无论 C++ 编译器确定它是什么类型)

      【讨论】:

      • 这在使用术语 ancestor 和使用继承的示例中有点误导。当然可以,但它做得更多,如果其中一种类型 convertible 到另一种,它将选择第二种类型,例如 (true? 1, 1.) 的类型为 doubleint可转换为 double,尽管没有 ancestorinheritance
      猜你喜欢
      • 2014-03-25
      • 2016-03-28
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多