C + + template parameter implementation of length and typeat in Loki
First, the length and typeat simulations in the original Loki are implemented as follows
1, template file
/********************************** ** author : szyu* * date : 2017.1.7***************************************/#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 &NBSP;TYPELIST_1 (type1) TypeList<type1, NullType> #define typelist_2(type1, type2) typelist<type1, typelist_1 (type2) > #define &NBSP;TYPELIST_3 (type1, type2, type3) typelist<type1, typelist_2 (type2, &NBSP;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, test case
/********************************** ** author : szyu** date : 2017.1.7***************************************/#include "loki.h" Voidtest1 () { 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 (&NBSP;DOUBLE,&NBSP;STD::STRING,&NBSP;STD ::vector<int>), 1>::result var2; var2 = "abc"; typeat<typelist_3 ( double, std::string, std::vector<int>), 2>:: Result var3; var3 = intvector;} Intmain ( int argc, char *argv[] ) { test1 (); return 0;}
3, the execution results are as follows:
650) this.width=650; "Src=" Http://s5.51cto.com/wyfs02/M00/8C/96/wKiom1hwZRCgwvOcAAECq3LYlU8920.png-wh_500x0-wm_3 -wmp_4-s_498185450.png "title=" screen shot 2017-01-07 11.48.07.png "alt=" Wkiom1hwzrcgwvocaaecq3lylu8920.png-wh_50 "/>
Second, improve length and typeat using c++11 template parameter characteristics
There are complex typelist nesting issues when you don't use templates, although using a macro definition can increase code readability, but you also need to define a large number of macros to support. When hundreds of parameters (extreme) are present, it is necessary to define hundreds of macros. Obviously more troublesome. C++11 provides support for the template's variable parameters, so the variable parameter implementation length and Typeat are as follows:
1, header file
/********************************** ** 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, test case
/********************************** ** author : szyu** date : 2017.1.6************************************/#include "TypeList.h" Voidtest1 () { std::cout << "Length<int> ..." << length<int>::value << std::endl; std::cout << " Length<int, int> ... "&NBSP;<<&NBSP;LENGTH<INT,&NBSP;INT>::VALUE&NBSP;<<&NBSP;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,&NBSP;INT,&NBSP;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"; &NBSP;&NBSP;&NBSP;&NBSP;TYPEAT<3,&NBSP;INT,&NBSP;STD::STRING,&NBSP;STD: : Vector<int> >::result var3; var3 = intvector;} Intmain ( int argc, char *argv[] ) { test1 (); return 0;}
3, execution results
650) this.width=650; "Src=" Http://s1.51cto.com/wyfs02/M02/8C/96/wKiom1hwZwfy211dAADe_iuRqAY657.png-wh_500x0-wm_3 -wmp_4-s_3527586635.png "title=" screen shot 2017-01-07 11.56.29.png "alt=" Wkiom1hwzwfy211daade_iurqay657.png-wh_50 "/>
In the implementation of Typeat, the position parameter is moved to the first parameter of the template because the parameter is to be located in the last argument.
Live:
Details of length and typeat in Loki see "new thinking on C + + design"
This article is from the "11988200" blog, please be sure to keep this source http://11998200.blog.51cto.com/11988200/1889957
[C + + templates] Length and typeat in Loki use c++11 properties to improve