您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何使用C++模板變參實現Loki中的Length和TypeAt,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
一,原Loki中的Length和TypeAt模擬實現如下
1,模板文件
#ifndef __SZYU_LOKI__ #define __SZYU_LOKI__ #include <iostream> #include <vector> template <typename T, typename U> class TypeList { public: typedef T Head; typedef U Tail; }; class NullType; #define TYPELIST_1(type1) TypeList<type1, NullType> #define TYPELIST_2(type1, type2) TypeList<type1, TYPELIST_1(type2)> #define TYPELIST_3(type1, type2, type3) TypeList<type1, TYPELIST_2(type2, type3)> /******************************************* * * Loki Length * **********************************************/ template <typename T> class Length; template <typename T, typename U> class Length<TypeList<T, U> > { public: enum { value = 1 + Length<U>::value }; }; template <> class Length<NullType> { public: enum { value = 0 }; }; /******************************************* * * Loki TypeAt * **********************************************/ template <typename T, unsigned int index> class TypeAt; template <typename T, typename U, unsigned int index> class TypeAt<TypeList<T, U>, index> { public: typedef typename TypeAt<U, index - 1>::Result Result; }; template <typename T, typename U> class TypeAt<TypeList<T, U>, 0> { public: typedef T Result; }; #endif
2,測試用例
/********************************** * * Author : szyu * * Date : 2017.1.7 * **************************************/ #include "loki.h" void test1() { std::cout << "Length<TYPELIST_1(int)>..." << Length<TYPELIST_1(int)>::value << std::endl; std::cout << "Length<TYPELIST_2(int, int)>..." << Length<TYPELIST_2(int, int)>::value << std::endl; std::cout << "Length<TYPELIST_3(int, int, int)>..." << Length<TYPELIST_3(int, int, int)>::value << std::endl; std::cout << "************************************" << std::endl; std::vector<int> IntVector; std::cout << typeid(TypeAt<TYPELIST_3( double, std::string, std::vector<int>), 0>::Result).name() << std::endl; std::cout << typeid(TypeAt<TYPELIST_3( double, std::string, std::vector<int>), 1>::Result).name() << std::endl; std::cout << typeid(TypeAt<TYPELIST_3( double, std::string, std::vector<int>), 2>::Result).name() << std::endl; TypeAt<TYPELIST_3( double, std::string, std::vector<int>), 0>::Result var1; var1 = 10.10; TypeAt<TYPELIST_3( double, std::string, std::vector<int>), 1>::Result var2; var2 = "abc"; TypeAt<TYPELIST_3( double, std::string, std::vector<int>), 2>::Result var3; var3 = IntVector; } int main( int argc, char *argv[] ) { test1(); return 0; }
3,執行結果如下:
二,使用C++11模板變參特性改進Length和TypeAt
在不使用模板變參會出現繁雜的TypeList嵌套問題,雖然使用宏定義能增加代碼可讀性,但是也因此需要定義大量的宏來支持。當出現幾百個參數(極端)情況下,那需要定義幾百個宏。顯然比較麻煩。C++11提供了模板的變參的支持,故變參實現Length和TypeAt如下:
1,頭文件
/********************************** * * Author : szyu * * Date : 2017.1.6 * ***********************************/ #ifndef __SZYU_LOKI__ #define __SZYU_LOKI__ #include <iostream> #include <vector> /*********************************** * * Loki length * ***************************************/ template <typename T, typename... Args> class Length { public: enum { value = 1 + Length<Args...>::value }; }; template <typename T> class Length<T> { public: enum { value = 1 }; }; /*********************************** * * Loki TypeAt * ***************************************/ template <unsigned int index, typename T, typename... Args> class TypeAt { public: typedef typename TypeAt<index - 1, Args...>::Result Result; }; template <typename T, typename... Args> class TypeAt<1, T, Args...> { public: typedef T Result; }; #endif
2,測試用例
/********************************** * * Author : szyu * * Date : 2017.1.6 * ***********************************/ #include "TypeList.h" void test1() { std::cout << "Length<int>..." << Length<int>::value << std::endl; std::cout << "Length<int, int>..." << Length<int, int>::value << std::endl; std::cout << "Length<int, int, char>..." << Length<int, int, char>::value << std::endl; std::cout << "********************************" << std::endl; std::vector<int> IntVector; std::cout << typeid(TypeAt<1, int, std::string, std::vector<int> >::Result).name() << std::endl; std::cout << typeid(TypeAt<2, int, std::string, std::vector<int> >::Result).name() << std::endl; std::cout << typeid(TypeAt<3, int, std::string, std::vector<int> >::Result).name() << std::endl; TypeAt<1, int, std::string, std::vector<int> >::Result var1; var1 = 10; TypeAt<2, int, std::string, std::vector<int> >::Result var2; var2 = "ssss"; TypeAt<3, int, std::string, std::vector<int> >::Result var3; var3 = IntVector; } int main( int argc, char *argv[] ) { test1(); return 0; }
3,執行結果
TypeAt的實現中,由于變參要位于最后一個參數,故把位置參數移到了模板第一個參數。
關于“如何使用C++模板變參實現Loki中的Length和TypeAt”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。