boost::preprocessor库之嵌套循环及其它
通过上面几篇文章,我们已经初步了解了pp库的作用。然而我们在实际编程中,肯定会碰到一些较为复杂的问题,这就要求我们要学会使用pp库的在线文档(请访问boost.org来搜索pp库的电子文档)。
比如,我们很有可能遇到多重嵌套循环的需求,然而宏语言对于这些我们平时司空见惯的编程逻辑还能力有限。下面我们来看一个2层深度的嵌套样例:
#ifndef BOOST_PP_IS_ITERATING
// we are in normal file
#include <boost/preprocessor/iteration/iterate.hpp>
#define M 3
#define BOOST_PP_ITERATION_LIMITS (1,M)
#define BOOST_PP_FILENAME_1 "test.cpp"
#include BOOST_PP_ITERATE()
#else // now we are in loop
// get d = depth of current loop
// get n = index of current loop
#define d BOOST_PP_ITERATION_DEPTH()
#define n BOOST_PP_ITERATION()
#if d == 1 // depth 1 loop
void BOOST_PP_CAT(foo, n) ()
{
#define BOOST_PP_ITERATION_LIMITS (1,n)
#define BOOST_PP_FILENAME_2 "test.cpp"
#include BOOST_PP_ITERATE()
}
#endif // depth 1
#if d == 2 // depth 2 loop
// get m = index of upper loop
#define m BOOST_PP_FRAME_ITERATION(1)
BOOST_PP_CAT(foo, n) = BOOST_PP_CAT(foo, m) + 1;
#endif // depth 2
#endif // BOOST_PP_IS_ITERATING
我们可以看出,这段代码运用了自我文件重复,并且有两曾重复。第一层重复使用BOOST_PP_FILENAME_1,而第二层重复使用BOOST_PP_FILENAME_2。无论对于哪曾循环,我们都可以通过ITERATION_DEPTH()获得当前嵌套循环的深度,也就等同于调用该循环的那个FILENAME_x的x值。而ITERATION()则始终返回当前循环下的索引。而如果我们在循环体里需要获得上层循环的索引时该怎么办呢?这就需要使用FRAME_ITERATION(d),这个宏则可以用了返回d层循环的索引。下面我们看看该段代码的输出:
void foo1 ()
{
foo1 = foo1 + 1;
}
void foo2 ()
{
foo1 = foo2 + 1;
foo2 = foo2 + 1;
}
void foo3 ()
{
foo1 = foo3 + 1;
foo2 = foo3 + 1;
foo3 = foo3 + 1;
}
请对比阅读输出和程序,体会多重嵌套的循环。
另外一个比较有用的宏函数是BOOST_PP_IF,请查阅在线文档搜索一下该函数的文档,你会发现其格式如下:
BOOST_PP_IF(cond, t, f)
比如我们要根据索引的单双,来输出文字,可以这样使用:
BOOST_PP_IF((BOOST_PP_MOD(n,2) == 0), "even", "odd")
好了,关于boost::preprocessor库的介绍就到此为止,其它的内容,请结合实际情况,查阅在线文档来解决吧。

十二月 23rd, 2008 at 02:02
找到一篇可以沙发的。哈哈,老所,您….囧啊。我闪去睡觉。
十二月 23rd, 2008 at 13:05
先测试下2.7的回复,呵呵。
十二月 23rd, 2008 at 13:06
@sofish 晕,这篇文章终于有沙发了:)