了解类型特征的体系结构

Vin*_*nod 5 c++ type-traits c++17

根据我目前对的理解,我想以最好的方式来表达这个问题type traits

我的理解是,所有模板类都type traits继承自std::integral_constant,它包装了value实例化模板类及其的表示形式type。此外,如其定义所示,中的通用模板类type traits继承自的辅助别名模板std::integral_constant,即std::bool_constant

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

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

在一个实例的情况下 std::is_arithmetic<2>,如果假设基地是std::integral_constant<typename T, T v>T成为intv成为2。但是,由于大多数通用模板类type traits显然都继承自std::bool_constant,因此基类实例化首先如何发生?由继承者返回的将值(可能)转换为trueor 的基础逻辑是什么?falseoperator bool

L. *_* F. 7

这是可能的实现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; }
};
Run Code Online (Sandbox Code Playgroud)

因此,有三种方法可以访问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>;
Run Code Online (Sandbox Code Playgroud)

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

template <typename T, typename U>
struct is_same :false_type {};
template <typename T>
struct is_same<T, T> :true_type {};
Run Code Online (Sandbox Code Playgroud)

它从导出true_type(即integral_constant<bool, true>)如果类型是相同的,或false_type(即integral_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
Run Code Online (Sandbox Code Playgroud)

您还可以使用::type提取基础integral_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>{});
Run Code Online (Sandbox Code Playgroud)

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

static_assert(is_same_v<int, int>);      // since C++17
Run Code Online (Sandbox Code Playgroud)

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

template <typename T, typename U>
inline constexpr bool is_same_v = is_same<T, U>::value;
Run Code Online (Sandbox Code Playgroud)