提问人:Vinod 提问时间:7/24/2019 更新时间:7/24/2019 访问量:252
了解类型特征的体系结构
Understanding the architecture of type traits
问:
我想根据我目前对 .type traits
我的理解是,所有模板类都继承自 ,它包装了模板类实例化的表示形式及其对应的 .此外,中的常见模板类继承自 的帮助程序别名模板,即 ,如其定义所示。type traits
std::integral_constant
value
type
type traits
std::integral_constant
std::bool_constant
例如,在 的情况下,继承自 的类型是 ,这意味着模板类继承自 。此外,模板类还从其基础基继承了 ,该基应该将对象转换为 和 (可能将其作为结果返回 )。std::is_arithmetic
value
std::integral_constant
bool
std::bool_constant
std::is_arithmetic
operator bool
bool
value
所以我的问题是:整个语义是如何联系在一起的?
在 的实例中,如果假设基数是 ,则 变为 和 变为 。但是,由于大多数常见的模板类显然继承自 ,那么基类实例化首先是如何发生的呢?继承返回的(可能)将值转换为 或 的底层逻辑是什么?std::is_arithmetic<2>
std::integral_constant<typename T, T v>
T
int
v
2
type traits
std::bool_constant
true
false
operator bool
答:
以下是以下可能的实现: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_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
还可以用于提取基础基类,并提取值的类型:::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>{});
在 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;
评论
std::is_arithmetic<2>
std::is_arithmetic<int>
std::is_arithmetic<MyClass>