这个版本中的亮点应该是变参模板了,变参模板在C++0x应该也有提到(未确认),实用性也很强,但一般是用在型参模板中。值参模板有很多种替代品,并不是十分需要这个特性。C++ 98标准中的模板并不支持变参模板,Loki中解决这类问题用的是模板默认值,代码写出来不太好看,而且参数数量也有限制,你必须假设一个足够多的参数个数。
我简单地看了一下,它似乎只算是个语法糖,并没有真正成为一个合理的实现,比如你无法从这些类型参数中析取出任何一个,而只能作为一个整体使用,即便是作值参使用时也是如此,这就降低了它的实用性,甚至D文档中也没有给出一个漂亮的应用。
我所说的“合理的实现”,大概类似这样的使用方式:
template TypeList(T, U){ typedef T Head; typedef U Tail; } template MakeTypeList(FistType, Types ...){ typedef TypeList!(FirstType, MakeTypeList!(Types).Result) Result; } template MakeTypeList(){ typedef NullType Result; }
这是Loki::TypeList的实现原理,但是用这个“漂亮的变参模板”来写要好看多了。当然遗憾的是它没有实现出来。
--------------------------------------
补充:
上面说到语法糖,实际上它把 Types ... 类型当作一个类型的tuple,比如接受的类型参数是int, float, char,则这个Types的类型是(int, float, char),你不能用它来做很多事,只有几个特殊用法。本来不需要自己再写type list的,这个tuple已经是一个type list了,但目前它只能整体使用,不能析取出任何一个类型,只能取到length,如果能增加一些对它进行操作的属性或方法就完整了,大概只需要再增加slice操作,它应该可以取到某一个元素(返回一个模板参数,可能是个类型),或者取到一组元素(本身是tuple类型,可能包含值或类型)。下面是有slice操作符以后的使用方式:
typedef void NullType; template TypeList(T, U){ typedef T Head; typedef U Tail; } template MakeTypeList(Types ...){ static if (Types.length == 0) typedef NullType Result; else typedef TypeList!(Types[0], MakeTypeList!(Types[0 .. length]).Result) Result; }
或者是稍漂亮点的:
typedef void NullType; template TypeList(T, U){ typedef T Head; typedef U Tail; } template MakeTypeList!(){ typedef NullType Result; } template MakeTypeList(Types ...){ typedef TypeList!(Types[0], MakeTypeList!(Types[0 .. length]).Result) Result; }
这又需要增强模板参数匹配功能,直到可以实现前面提到的用法:
template TypeList(T, U){ typedef T Head; typedef U Tail; } template MakeTypeList(FistType, Types ...){ typedef TypeList!(FirstType, MakeTypeList!(Types).Result) Result; } template MakeTypeList(){ typedef NullType Result; }
继续等。