std :: common_type实现

时间:2012-09-05 21:27:10

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

为了了解它是如何工作的,我在标题std::common_type中查看了type_traits的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;
    };

我完全理解第一,第二和第四声明的工作原理。但是,我无法理解第三个声明的工作原理。有人可以尝试解释这里使用的机制吗?

3 个答案:

答案 0 :(得分:10)

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

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

T0T1中最专业的常见类型。剩下的就是将这个表达式转换为一个类型并确保它不被评估。 decltype(expr)就是这样做的。显然,逻辑的两个论证版本:其他的是处理角落案例(一个论证)并利用两个论证版本来产生任意类型的共同类型。

答案 1 :(得分:3)

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

简单地说,表达式:

boolean-expression ? second-operand : third-operand

有一个&#34;普通类型&#34;第二和第三个操作数,如果存在的话。然后decltype说明符用于&#34;转换&#34;将表达式转换为类型说明符。

答案 2 :(得分:1)

Long Story Short:decltype使C ++编译器确定最接近它的祖先类型。

第三级算子具有两种可能表达式中最接近祖先的静态类型。

E.g:

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 ++编译器决定它的类型)