boost::preprocessor库之嵌套循环及其它

四月 8th, 2008 by Soloman | Print boost::preprocessor库之嵌套循环及其它 | 525 views

通过上面几篇文章,我们已经初步了解了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库的介绍就到此为止,其它的内容,请结合实际情况,查阅在线文档来解决吧。

, , ,

 

本文有3条评论

  1. sofish 说: [回复]

    找到一篇可以沙发的。哈哈,老所,您….囧啊。我闪去睡觉。

  2. Soloman 说: [回复]

    先测试下2.7的回复,呵呵。

  3. Soloman 说: [回复]

    @sofish 晕,这篇文章终于有沙发了:)

Other Discussion on This Post

  1. 老所工作室 » boost::preprocessor库使用入门

添加评论 (支持Gravatar头像)

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。

实时评论预览