本文属spanzhang原创,其blog地址为:http://blog.csdn.net/spanzhang。引用或转贴请注明出处,谢谢!!
C++ Meta Programming基本上都是用template来做,它是Generic Programming的一种。个人认为这个东西在实际的开发中不是特别有用,至少我还没有实际用过。TML(Type Manipunation Library)是作者开发的一个C++ Meta Programming库,它是纯粹为研究目的而写的。如果你看了代码不头晕,说明你心理抵抗力比较强!在TML中,所有的代码都运行在编译期,它只对类型做操作而不对数据做操作。在整体结构上和Standard Template Library (STL)相似,所不同的是TML将类型放入容器中进行操纵而STL将数据放入容器中进行操纵。当然,我这个小玩意还没有完全成型,就算成型了也不可能与STL相提并论。下面先从原理上来进入TML正题:
1、灵感来源(TML的基础)
看看下面的一个模板类:
template <typename A, typename B>
class someName
{
typedef CASE<1, A,
CASE<2, B
> > type_list;
typedef FIND<type_list, 2>::RET RETURN;
public:
typedef RETURN RET;
};
这个类有两个模板参数,在内部公共域仅提供了一个类型定义。我们将它翻译成如下格式:
META_PARAMETERS<META_PARAM A, META_PARAM B>
META_FUNCTION someName
{
META_VAR CASE<1, A,
CASE<2, B
> > type_list;
META_VAR FIND<type_list, 2>::RET RET;
META_RETURN:
META_VAR RET RETURN;
};
这样,原来的模板参数变成了函数参数,原来的类名someName变成了函数名,原来的类定义变成了函数体,以前的类私有域变成了函数执行运算的部分而公共域成了函数的返回部分。这样以来,我们可以做如下的定义(或者,现在应该叫运算才对):
META_VAR someName<clsA, clsB>::RETURN clsResult;
这个语句不会在运行期产生任何内存分配行为,而对于编译期来将将生成了一个新的类型。OK,TML的基本东西就这么多了。如下的一些宏构成了TML的基础部分:
#define META_EQUAL_TO :public
#define META_IS :public
#define META_FUNCTION class
#define META_PARAMETERS template
#define META_RETURN public
#define META_VAR typedef
#define META_PARAM typename
#define META_CONST(name,value) enum { name = (value) };
2、语句、运算和循环
TML的语句相对来说简单得多,一个最基本条件判断语句如下:
META_PARAMETERS<bool condition, META_PARAM Then, META_PARAM Else>
META_FUNCTION IF
{
META_PARAMETERS<int _condition>
META_FUNCTION Select { META_RETURN: META_VAR Then RET; };
META_FUNCTION Select<false> { META_RETURN: META_VAR Else RET; };
META_RETURN:
META_VAR Select<condition>::RET RET;
};
实现的时候是通过一个嵌套类Select的特化来完成判断操作。另外,说一句题外题内话,TML的所有返回都叫RET而不叫RETURN是因为写起来麻烦。
TML也有一些运算符,比如:
META_PARAMETERS<META_PARAM UnaryFunc1, META_PARAM UnaryFunc2>
META_FUNCTION OR META_IS UNARY_FUNCTION
{
META_RETURN:
META_PARAMETERS<typename Arg>
META_FUNCTION EXEC
{
META_RETURN:
META_CONST(RET, (EXEC_UNARY_FUNCTION<UnaryFunc1, Arg>::RET
||EXEC_UNARY_FUNCTION<UnaryFunc2, Arg>::RET));
};
};
我估计,你看到这段代码后根本就不知道它原来就是逻辑运算符OR的实现。其它的一些运算符号以后介绍。接下来一个比较头痛的事情是循环。在TML里,所有的循环都是通过类型迭代来完成的,什么是类型迭代,哎,我都岗不清楚,只可意会。看下面的例子:
META_PARAMETERS<META_PARAM MapList, META_PARAM Tag, META_PARAM Value>
META_FUNCTION PUSH_FRONT
{
META_VAR MapList::NEXT nextMap;
META_VAR MapList::VALUE VALUE;
META_VAR MapList::TAG TAG;
META_VAR MapList::PRIOR_TAG PRIOR_TAG;
META_VAR nextMap::TAG nextTAG;
META_VAR IF<
IS_SAME_TYPE::EXEC<nextTAG, map_private::END_NODE>::RET,
map_private::END_NODE,
PUSH_FRONT<nextMap, Tag, Value>
>::RET nextPushFront;
META_VAR IF<
IS_SAME_TYPE::EXEC<nextTAG, map_private::END_NODE>::RET,
map_private::MAP_NODE< TAG, VALUE, PRIOR_TAG, map_private::MAP_NODE<Tag, Value, TAG> >,
map_private::MAP_NODE< TAG, VALUE, PRIOR_TAG, nextPushFront::RET >
>::RET RET1;
META_RETURN:
META_VAR IF<
SIZE<MapList>::Value == 0,
map_private::MAP_NODE<Tag, Value>,
RET1
>::RET RET;
}; //PUSH_FRONT
nextPushFront在这里起到了关键的作用,它让类型迭代而产生我们想要的循环效果,最终从迭代的出口处得到我们想要的结果(RET)。
好了,TML的全部基础介绍完毕,这里下载。顺便提一句,长沙今天天气不错,很就没出太阳了。