了解类型特征的体系结构

Understanding the architecture of type traits

提问人:Vinod 提问时间:7/24/2019 更新时间:7/24/2019 访问量:252

问:

我想根据我目前对 .type traits

我的理解是,所有模板类都继承自 ,它包装了模板类实例化的表示形式及其对应的 .此外,中的常见模板类继承自 的帮助程序别名模板,即 ,如其定义所示。type traitsstd::integral_constantvaluetypetype traitsstd::integral_constantstd::bool_constant

例如,在 的情况下,继承自 的类型是 ,这意味着模板类继承自 。此外,模板类还从其基础基继承了 ,该基应该将对象转换为 和 (可能将其作为结果返回 )。std::is_arithmeticvaluestd::integral_constantboolstd::bool_constantstd::is_arithmeticoperator boolboolvalue

所以我的问题是:整个语义是如何联系在一起的?

在 的实例中,如果假设基数是 ,则 变为 和 变为 。但是,由于大多数常见的模板类显然继承自 ,那么基类实例化首先是如何发生的呢?继承返回的(可能)将值转换为 或 的底层逻辑是什么?std::is_arithmetic<2>std::integral_constant<typename T, T v>Tintv2type traitsstd::bool_constanttruefalseoperator bool

C++ C++17 类型特征

评论

1赞 7/24/2019
我想,你不会使用类似 , .据我所知,类型特征对类型起作用,而不是对值起作用。std::is_arithmetic<2>std::is_arithmetic<int>std::is_arithmetic<MyClass>
0赞 Vinod 7/24/2019
@generic_opto_guy同意

答:

6赞 L. F. 7/24/2019 #1

以下是以下可能的实现:integral_constant

template <typename T, T v>
struct integral_constant {
    static constexpr T value = v;

    using value_type = T;
    using type = integral_constant; // the current instantiation

    constexpr   operator T() const noexcept { return v; }
    constexpr T operator()() const noexcept { return v; }
};

因此,有三种方法可以访问(或从中派生的类)的值:integral_constant

  • integral_constant<T, v>::value,其中使用静态数据成员;value

  • integral_constant<T, v>{}(),其中 在 类型的对象上调用 ;和operator()integral_constant<T, v>

  • integral_constant<T, v>{}隐式转换为布尔值。

bool_constant只是一个别名模板:

template <bool B>
using bool_constant = integral_constant<bool, B>;

using true_type = bool_constant<true>;
using false_type = bool_constant<false>;

现在让我们考虑一个实际的类型特征。举个例子:is_same

template <typename T, typename U>
struct is_same :false_type {};
template <typename T>
struct is_same<T, T> :true_type {};

如果类型相同,则派生自 (即 ),否则派生自 (即 )。因此,您可以通过上述三种方式使用它:true_typeintegral_constant<bool, true>false_typeintegral_constant<bool, false>

static_assert(is_same<int, int>::value); // use ::value member
static_assert(is_same<int, int>{}());    // use operator()
static_assert(is_same<int, int>{});      // use operator bool

还可以用于提取基础基类,并提取值的类型:::typeintegral_constant::value_type

static_assert(is_same<true_type, is_same<int, int>::type>{});
static_assert(is_same<bool, is_same<int, int>::value_type>{});

在 C++ 17 中,我们有另一种访问值的方法:.is_same_v<int, int>

static_assert(is_same_v<int, int>);      // since C++17

这不是魔术; 只是一个变量模板,它被定义为相应的值:is_same_v

template <typename T, typename U>
inline constexpr bool is_same_v = is_same<T, U>::value;