模版元编程:C++11中type traits的部分实现

Posted OshynSong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模版元编程:C++11中type traits的部分实现相关的知识,希望对你有一定的参考价值。

C++11新加入的type_traits头文件提供了模版元编程中常用的type trait基础设施,这些type traits基于编译期间的运算,能够极早提示出程序中的错误。这些type traits的基础就是整形包装器,见之前的博文总结:http://blog.csdn.net/u010487568/article/details/51273920。本文对type traits的部分进行总结和实现。

主类型归类

主要是判断语言提供的基础类型,包括数组、类、enum、union、指针、引用、函数、右值引用、成员函数指针、成员对象指针、void。这些类型归类都是继承自integral_constant这个整形包装器。下面提供部分实现。
这些基础类型都是基于模版偏特化即可实现,但偏特化需要考虑全面,下面以is_array说明。

template<class T> struct is_array : std::false_type ;

//偏特化一维数组
template<class T> struct is_array<T[]> : std::true_type ;

//偏特化多维数组
template<class T, std::size_t N> struct is_array<T[N]> : std::true_type ;

其余指针、引用实现相似,不过需要考虑const、volatile等修饰,其中函数还需要考虑const、volatile、noexcept修饰,以及可变参数与可变模版参数两种不同特化及这些组合。

// primary template
template<class>
struct is_function : std::false_type  ;

// specialization for regular functions
template<class Ret, class... Args>
struct is_function<Ret(Args...)> : std::true_type ;

// specialization for variadic functions such as std::printf
template<class Ret, class... Args>
struct is_function<Ret(Args......)> : std::true_type ;

// specialization for function types that have cv-qualifiers
template<class Ret, class... Args>
struct is_function<Ret(Args...)const> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)const> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)volatile> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)const volatile> : std::true_type ;

// specialization for function types that have ref-qualifiers
template<class Ret, class... Args>
struct is_function<Ret(Args...) &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)const &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......) &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)const &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)volatile &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)const volatile &> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...) &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)const &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......) &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)const &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)volatile &&> : std::true_type ;
template<class Ret, class... Args>
struct is_function<Ret(Args......)const volatile &&> : std::true_type ;

//...针对noexcept继续组合上述偏特化版本

另一类需要对模版参数先remove cv操作从而再进行偏特化,如is_member_function_pointer:

template<class T> struct is_member_function_pointer_test : false_type ;
template<class T, class U> struct is_member_function_pointer_test<T U::*> : true_type ;

template<class T> struct is_member_function_pointer : is_member_function_pointer_test<std::remove_cv<T>::type> ;

复合类型

根据上述基础类型的组合,就可以构建复合类型归类

复合类型组合
is_arithmeticis_integral
is_foundamentalis_arithmetic
is_compound! is_arithmetic
is_objectis_scalar
is_scalar! is_arithmetic

类型间关系

基于编译器的类型关系规则,也就是语言规范进行编译期间的类型关系判断。支持is_sameis_base_ofis_convertible三个。实现如下:

template<class T, class U> struct is_same : std::false_type ;
template<class T> struct is_same<T, T> : std::true_type ;

//基于编译器(语言规范)的重载函数调用时的参数最优匹配规则
//通用泛型指针版本
template<class B> std::false_type is_base_of_test_func(void *);
//重载的基类指针版本
template<class B> std::true_type is_base_of_test_func(B *);

template<class B, class D>
using result_for_is_base_of = decltype(is_base_of_test_func<B>(std::declval<D*>()));

template<class B, class D>
struct is_base_of :
    public std::conditional_t<
        std::is_class<B>::value && std::is_class<D>::value,
        result_for_is_base_of<B, D>,
        std::false_type
    > ;

类型转换

同样提供了偏特化方式对const、volatile、reference、pointer、cv进行特化,提供add和remove两种操作。下面以remove_extent举例,改类型转换可以将一个数组去掉最低的一维,返回去掉后的类型。

template<class T> struct remove_extent using type = T;;
template<class T> struct remove_extent<T[]> using type = T;;
template<class T, size_t N> struct remove_extent<T[N]> using type = T;;

条件选择

提供了conditionalenable_if两种选择。

template<bool x, class T, class U> struct conditional using type = T;
template<class T, class U> struct conditional<false, T, U> using type = U;

template<bool x, class T=void> struct enable_if ;
template<class T> struct enable_if<true, T> using type = T;;

暂总结与此,待续!

以上是关于模版元编程:C++11中type traits的部分实现的主要内容,如果未能解决你的问题,请参考以下文章

SFINAE 与 type_traits

初识C++模板元编程(Template Mega Programming)

C++范型编程 -- <type_traits>头文件

std type_traits 与 Qt type_traits 冲突

STL源码分析--traits

模板Trait 技术与简述template 元编程