根据我目前对 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
,基类实例化首先是如何发生的?值(value)(可能)转换为 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。
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;
关于c++ - 理解类型特征的架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57175680/