1 函数相关
1 is_function
检查该类型是否是函数类型
注意:如果传入的是一个函数指针类型,需要使用 remove_pointer
去掉指针
标准库使用了一个技巧,先给传入的类型加 const 关键字修饰,之后再判断该类型是否为 const 。
- 如果是普通的数据类型,包括内置类型,类、引用类型或各类指针类型。
is_const<const _Tp>::value
是 true。 - 如果是函数类型。
is_const<const _Tp>::value
依然是 false。
// 变量模板,简化类模板的书写
template <typename _Tp>
inline constexpr bool is_function_v = is_function<_Tp>::value;
template<typename _Tp>
struct is_function
: public __bool_constant<!is_const<const _Tp>::value> { };
template<typename _Tp>
struct is_function<_Tp&>
: public false_type { };
template<typename _Tp>
struct is_function<_Tp&&>
: public false_type { };
2 is_invocable
判断 函数类型、函数指针类型 或 函数对象类型 是否与参数相匹配
template<typename _Fn, typename... _Args>
inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
3 is_invocable_r
判断 在
is_invocable
条件下,返回值类型 是否与Ret
相匹配
template<typename _Ret, typename _Fn, typename... _Args>
inline constexpr bool is_invocable_r_v
= is_invocable_r<_Ret, _Fn, _Args...>::value;
2 类相关
1 is_base_of
两个类是否具有继承关系
// 注意基类和派生类的位置
template <typename _Base, typename _Derived>
inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value;
2 is_constructible
用于检查 _Tp 类型是否可以使用 _Args 一系列参数进行构造
template <typename _Tp, typename... _Args>
inline constexpr bool is_constructible_v =
is_constructible<_Tp, _Args...>::value;
3 检查是否为指定类型
1 __is_tuple_like
检查该类型是否为tuple类型
通过 __is_tuple_like_impl
特例化两个版本来分别处理类型为 tuple 和 非tuple 两种情况。
template<typename> //忽略的类型参数名,因为不使用
struct __is_tuple_like_impl : false_type
{ };
template<typename... _Tps> //将_Tp 特化为 tuple<_Tps...>类型
struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
{ };
template<typename _Tp>
struct __is_tuple_like //下面是去掉tuple类型的 cv和引用限定符。如果不去掉,并不一定会优先匹配特化版本
: public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type
{ };
- 可以通过定义一个变量模板类简化书写
template <typename _Tp>
constexpr bool is_tuple_v = std::__is_tuple_like<_Tp>::value;
4 检查修饰词
有i相关的一系列函数
1 is_const
类型是否被顶层const修饰
template<typename>
struct is_const
: public false_type { };
template<typename _Tp>
struct is_const<_Tp const>
: public true_type { };
5 其他
1 is_convertible
两个类型是否可隐式转换
// 注意 左边为源类型,右边为目标类型
template <typename _From, typename _To>
inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
比如:
bool f = std::is_convertible_v<std::string, std::string_view>;
bool f_ = std::is_convertible_v<std::string_view, std::string>;
// f = true, f_ = false
因为 string 类中定义了隐式转换为 string_view类的运算符函数,反之,没有。