跟我学c++高级篇——模板元编程之七typelist

一、typelist

怎么说呢?Typelists其实是《Modern c++ Design》中提出的。typelist的名字和list很有关系。学过c++开发的一定会知道STL库的几个常用的数据结构vector,list。list是链表的泛型表示。所以typelist是类型的“泛型”,当然这个泛型是加引号的。毕竟元编程中也没有这种定义,这么说是为了好理解。
而且typelist看上去不是很好看,对,就是不好看,不符合人们对list的认知习惯,看一下代码:

template <typename T,typename U>
struct Typelist
{
 typedef T Head;
 typedef U Tail;
};
typedef Typelist<char,Typelsit<int,Typelist<long,Typelist<short,NullType>>>> Ex;

这里需要说明一下,在早期版本的模板处理中,编译器有点二,不支持连续的模板标识“>>”,它们中间必须加一个空格。但是现在较高版本的编译器都没有问题,如果遇到这种问题,要么用高级的IDE,或者加个空格吧。
扯回来,看上去这个东西是不是完全和list不沾边,所以书上说要包装一下,包装能解决问题,和现实社会一样,五十的大姐姐,化妆后,变成了十五的小姐姐,看代码:

#define TYPELIST_1(T1) Typelist<T1,NullType>
#define TYPELIST_2(T1,T2) Typelist<T1,Typelist(T2)>
#define TYPELIST_3(T1,T2,T3) Typelist<T1,Typelist(T2,T3)>
#define TYPELIST_4(T1,T2,T3,T4) Typelist<T1,Typelist(T2,T3,T4)>
...
#define TYPELIST_50(...) ...

明白上面的代码,就基本掌握了typelist是个啥。

二、typelist本质

那么在早期的c++模板编程中,可以使用这种技巧来实现不同的类型的“泛型”,其本质就是使用了上一篇文中的template template parameters。其最终的目的就是动态的根据类型实现各种对象的创建(就像书提到的工厂)。这对于一些情况(如处理虚函数时),就会非常有效果。
也就是说,上面的代码生成过程,表现出来就是用模板的模板参数形式的。

typedef Typelist<char,Typelsit<int,Typelist<long,Typelist<short,NullType>>>> Ex;

写到这里,基本上就可以理清Typelist的动机和生成机制。那么,这种通过较为复杂的技巧实现Typelist方式有没有改进的方式呢?那必须有。不过得是在c++的新标准里,用前面提到的模板的变参化:

//声明
template<typename ... Args> class TypeList;
//偏特化实现
template<typename Head, typename ... Tail> class TypeList<Head, Tail...>;

//实现方法
template <typename T,typename U>
struct TypeNode
{
  typedef T Head;
  typedef U Tail;
};
template<typename Head, typename ...Tails>
struct TypeList
{
    using Result = TypeNode<Head, typename TypeList<Tails...>::Result>;
};

template<typename arg>
struct TypeList<arg>
{
    using R = TypeNode<H, NullType>;
};

所以说要想省事,还得从根儿进步。
这里不对Typelist的内部实现诸如查找、擦除进行分析,毕竟书上讲得很清楚。

三、Typelist的自动生成类

在MFC里曾经用宏的展开来自动生成类,复杂的很,几乎没人喜欢。然后用Typelist也可以生成类。下面看一个例子:

template <class TList,template<class> class Unit>
class Gen;
template <class T1,class T2,template<class> class Unit>
      :public Gen<T1,Unit>,public Gen<T2,Unit>{};
class Gen;
template <class AT,template<class> class Unit>
class Gen:public Unit<AT>;
template <template<class> class Unit>
class Gen<NullType,Unit>{};

使用Typelist可以用更技巧性template template parameters的方式来生成代码,这也难怪侯捷老师说这个技巧是比较深的模板技术,有兴趣还是要多多学习。
可以自动生成类,就可以在这其中加自己的料了,比如限制继承的顺序和继承的条件,这些都可以在上面这种模型的实现中进行操作。

四、总结

知其所以然,所以在元编程中使用这种技巧就会很方便。特别对于初学者,看一些大牛的代码,上来就是大片的宏再加上变参还有其它一些技巧,说句难听的,可能当下就蒙了,根本看不下去。如果去搜索,搞这类开发的本身就少,所以最终可能就是开始即放弃。但是如果从这些基础的方面入手,不断的拆解,就忽然发现,模板的元编程,还是能大胆的深入进去。
与诸君共同努力!

猜你喜欢

转载自blog.csdn.net/fpcc/article/details/129261414