c++11 type_traits类型萃取

一. c++ traits定义

type_traits使用模板技术来萃取类型(包含自定义类型和内置类型)的某些特性,用以判断该类型是否含有某些特性,从而在泛型算法中来对该类型进行特殊的处理用来提高效率或者其他。

通过type_traits可以实现在编译期计算、查询、判断、转换和选择,增强了泛型编程的能力,也增强了程序的弹性,使得我们在编译期就能做到优化改进甚至排错,能进一步提高代码质量。

二.几个栗子

http://www.cplusplus.com/reference/type_traits/?kw=type_traits
cplusplusreference网站列举出了一大堆。这里举几个栗子说明type_traits是怎么实现的(vs2019 stl源码)。

integral_constant

template <class _Ty, _Ty _Val>
struct integral_constant {
	// static 编译期常量。static是为了保证value变量只有一个。并且constexpr表明value必须是一个编译期常量。
    static constexpr _Ty value = _Val; 

    using value_type = _Ty;
    using type       = integral_constant;

    constexpr operator value_type() const noexcept {
        return value;
    }

    _NODISCARD constexpr value_type operator()() const noexcept {
        return value;
    }
};

注意上面定义的strct intergral_constant模板中

static constexpr _Ty value = _Val; 

如果没有constexpr修饰就会报编译错误:a static data member with an in-class initializer must have non-volatile const integral type
只能在其声明中初始化整数类型的常量静态成员,如果是非整数类型就会有问题。

true_type和false_type

template <bool _Val>
using bool_constant = integral_constant<bool, _Val>;

using true_type  = bool_constant<true>;
using false_type = bool_constant<false>;

is_integral

template <class>
_INLINE_VAR constexpr bool _Is_integral = false; // determine whether cv-unqualified type argument is integral

// 模板显式具体化(注意区分显式具体化和显式实例化)
template <>
_INLINE_VAR constexpr bool _Is_integral<bool> = true;

template <>
_INLINE_VAR constexpr bool _Is_integral<char> = true;

template <>
_INLINE_VAR constexpr bool _Is_integral<int> = true;

template <>
_INLINE_VAR constexpr bool _Is_integral<unsigned int> = true;

// ...这里只贴出以上四种特化版本,省略其它各种可以识别为整型的特化版本

template <class _Ty>
_INLINE_VAR constexpr bool is_integral_v = _Is_integral<remove_cv_t<_Ty>>; // determine whether _Ty is integral

template <class _Ty>
struct is_integral : bool_constant<is_integral_v<_Ty>> {};

由源码可以看出,std::is_integral通过实现各种整型类型的特化版本,来实现识别整型类型。
使用中通过识别std::is_integral::value为true/false。

is_reference 特化出左值引用和右值引用的版本

template <class>
_INLINE_VAR constexpr bool is_reference_v = false; // determine whether type argument is a reference

template <class _Ty>
_INLINE_VAR constexpr bool is_reference_v<_Ty&> = true;

template <class _Ty>
_INLINE_VAR constexpr bool is_reference_v<_Ty&&> = true;

template <class _Ty>
struct is_reference : bool_constant<is_reference_v<_Ty>> {};

is_const

template <class>
_INLINE_VAR constexpr bool is_const_v = false; // determine whether type argument is const qualified

template <class _Ty>
_INLINE_VAR constexpr bool is_const_v<const _Ty> = true;

template <class _Ty>
struct is_const : bool_constant<is_const_v<_Ty>> {};

is_same

template <class, class>
_INLINE_VAR constexpr bool is_same_v = false; // determine whether arguments are the same type
template <class _Ty>
_INLINE_VAR constexpr bool is_same_v<_Ty, _Ty> = true;

template <class _Ty1, class _Ty2>
struct is_same : bool_constant<is_same_v<_Ty1, _Ty2>> {};

enable_if

template <bool _Test, class _Ty = void> //泛化版本
struct enable_if {}; // no member "type" when !_Test

template <class _Ty> //偏特化版本(部分具体化)
struct enable_if<true, _Ty> { // type is _Ty for _Test
    using type = _Ty;
};

满足条件时类型有效。从源码可知只有当第一个模板参数为true时,type才有效。
否则访问type编译出错。通常做一些编译期的类型检查。
第二个参数有默认值void,所以如果不指定第二个参数,只是做check。
如果要用到type,需要指定第二个模板参数。
例如:

enable_if<true>::type   // void
enable_if<true, int>::type // int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值