根据目前对type traits
的理解,我想以最好的方式来表达这个问题。
我的理解是type traits
中的所有模板类都继承自std::integral_constant
,它包装了实例化模板类的value
及其对应的{{ 1}}。此外,type
中的通用模板类继承自type traits
的辅助别名模板,即std::integral_constant
,如其定义所示。
例如,在std::bool_constant
的情况下,从std::is_arithmetic
继承的value
的类型为std::integral_constant
,这意味着模板类从{{1} }。此外,模板类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
的基础逻辑是什么?
答案 0 :(得分:6)
这是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;