模版元編程: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_arithmetic is_integral
is_foundamental is_arithmetic
is_compound ! is_arithmetic
is_object is_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;};

暫總結與此,待續!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章