欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

type_traits类型萃取

程序员文章站 2022-03-23 10:49:06
...

一. 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 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;
    }
};

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编译出错。通常做一些编译期的类型检查。