给定任何类型 T 时手动区分类型
使用 std::enable_if
实现 SFINAE 时 ,访问辅助模板通常很有用,可以确定给定类型 T
是否与一组条件匹配。
为了帮助我们,该标准已经提供了两种类型的 true
和 false
,分别是 std::true_type
和 std::false_type
。
以下示例显示如何检测类型 T
是否为指针,is_pointer
模板模仿标准 std::is_pointer
帮助程序的行为:
template <typename T>
struct is_pointer_: std::false_type {};
template <typename T>
struct is_pointer_<T*>: std::true_type {};
template <typename T>
struct is_pointer: is_pointer_<typename std::remove_cv<T>::type> { }
上面的代码有三个步骤(有时你只需要两个):
-
is_pointer_
的第一个声明是默认情况,并继承自std::false_type
。在默认的情况下,应始终从std::false_type
继承,因为它是类似于一个“false
条件”。 -
第二个声明专门用于指示
T*
的is_pointer_
模板,而不关心T
究竟是什么。此版本继承自std::true_type
。 -
第三个声明(真正的声明)只是从
T
删除任何不必要的信息(在这种情况下我们删除了const
和volatile
限定符),然后回退到前两个声明中的一个。
由于 is_pointer<T>
是一个类,要访问它的值,你需要:
- 使用
::value
,例如is_pointer<int>::value
-value
是bool
的静态类成员,继承自std::true_type
或std::false_type
; - 构造一个这种类型的对象,例如
is_pointer<int>{}
- 这是因为std::is_pointer
从std::true_type
或std::false_type
(有constexpr
构造函数)继承了它的默认构造函数,std::true_type
和std::false_type
都有constexpr
转换运算符到bool
。
提供帮助程序帮助程序模板是一个很好的习惯,可以让你直接访问该值:
template <typename T>
constexpr bool is_pointer_v = is_pointer<T>::value;
Version >= C++ 17
在 C++ 17 及更高版本中,大多数帮助器模板已经提供了 _v
版本,例如:
template< class T > constexpr bool is_pointer_v = is_pointer<T>::value;
template< class T > constexpr bool is_reference_v = is_reference<T>::value;