type traits

C++ type traits 学习

从integral_constant引入

integral_constant是一个模板类,用于表示一个常量值,它的定义如下:

/// integral_constant
template<typename _Tp, _Tp __v>
struct integral_constant
{
    static constexpr _Tp                  value = __v;
    typedef _Tp                           value_type;
    typedef integral_constant<_Tp, __v>   type;
    // 类型转换运算符
    constexpr operator value_type() const { return value; }
#if __cplusplus > 201103L

#define __cpp_lib_integral_constant_callable 201304
    // 函数对象
    constexpr value_type operator()() const { return value; }
#endif
};

template<typename _Tp, _Tp __v>
constexpr _Tp integral_constant<_Tp, __v>::value;

/// The type used as a compile-time boolean with true value.
typedef integral_constant<bool, true>     true_type;

/// The type used as a compile-time boolean with false value.
typedef integral_constant<bool, false>    false_type;

这样想要在结构体或类中定义一个整型常量,则可以使该结构体或类继承自 std::integral_constant<type, val>,则该结构体内部就有了一个static const type的value,访问该value即可。

类型判断

以判断是否为整型为例,可以使用std::is_integral<T>,它的部分定义如下:

/// is_integral
template<typename _Tp>
struct is_integral
: public __is_integral_helper<typename remove_cv<_Tp>::type>::type
{ };

template<typename>
struct __is_integral_helper
: public false_type { };

template<>
struct __is_integral_helper<bool>
: public true_type { };

template<>
struct __is_integral_helper<char>
: public true_type { };

template<>
struct __is_integral_helper<signed char>
: public true_type { };

template<>
struct __is_integral_helper<unsigned char>
: public true_type { };

template<>
struct __is_integral_helper<short>
: public true_type { };

template<>
struct __is_integral_helper<unsigned short>
: public true_type { };

template<>
struct __is_integral_helper<int>
: public true_type { };

template<>
struct __is_integral_helper<unsigned int>
: public true_type { };

这里定义了一个模板类__is_integral_helper<T>,它继承自std::false_type,然后对于不同的整型进行了特化,继承自std::true_type。
这样可以直接使用std::is_integral<T>::value来判断T是否为整型,在编译期间就可以得到结果。

类型关系

判断是否为同一类型

template<typename, typename>
struct is_same
: public false_type { };

template<typename _Tp>
struct is_same<_Tp, _Tp>
: public true_type { };

判断是否为基类

template<typename _Base, typename _Derived>
struct is_base_of
: public __is_base_of<_Base, _Derived> { };

头文件中没有找到__is_base_of的定义。

判断能否类型转换

/// is_convertible
template<typename _From, typename _To>
struct is_convertible
: public __is_convertible_helper<_From, _To>::type
{ };

条件选择

在编译期根据一个判断式选择两个类型中的一个

/// Define a member typedef @c type to one of two argument types.
template<bool _Cond, typename _Iftrue, typename _Iffalse>
struct conditional
{ typedef _Iftrue type; };

// Partial specialization for false.
template<typename _Iftrue, typename _Iffalse>
struct conditional<false, _Iftrue, _Iffalse>
{ typedef _Iffalse type; };

条件禁用

在编译期根据一个判断式禁用一个模板

/// Alias template for enable_if
template<bool _Cond, typename _Tp = void>
using enable_if_t = typename enable_if<_Cond, _Tp>::type;

/// Define a member typedef @c type only if a boolean constant is true.
template<bool, typename _Tp = void>
struct enable_if
{ };

// Partial specialization for true.
template<typename _Tp>
struct enable_if<true, _Tp>
{ typedef _Tp type; };

可以用于特定类型的模板的禁用,以及函数的重载。

#include<iostream>
#define APP_VERSION 20181010L
unsigned int GetAppVersion0() { return APP_VERSION; }
struct GetAppVersion : public std::integral_constant<unsigned int, APP_VERSION> {
    GetAppVersion(){
        std::cout<<"in constructor"<<std::endl;
    }
};

template <typename T>
std::enable_if_t<std::is_integral<T>::value, T> f(T t)
{
    return t;
}

template <typename T>
typename std::enable_if<!std::is_integral<T>::value>::type f(T t)
{
    std::cout << t << std::endl;
}

int main()
{
    GetAppVersion app;
    // 函数
    std::cout << GetAppVersion0() << std::endl;
    // 类内部的常量
    std::cout << GetAppVersion::value << std::endl;
    // 临时对象
    std::cout << GetAppVersion() <<std::endl;
    // 函数对象
    std::cout << app() <<std::endl;
    // 类型转换
    std::cout << app <<std::endl;

    std::integral_constant<int,100> ic;
    std::cout<<ic.value<<std::endl;
    std::cout<<std::integral_constant<int,100>::value<<std::endl;
    std::cout<<ic()<<std::endl;
    std::cout<<ic<<std::endl;

    std::cout << std::is_integral<int>::value << std::endl;
    std::cout << std::is_same<int, int>::value << std::endl;
    std::cout << std::is_convertible<int, int>::value << std::endl;
    std::conditional<true, int, double>::type a = 1;
    std::cout << f(1) << std::endl;
    f(1.0);
    // std::cout << f(1.0) << std::endl;
    // f(1);

    return 0;
}
posted @ 2024-04-27 14:53  trashwin  阅读(11)  评论(0编辑  收藏  举报