Function
#include <boost/spirit/home/phoenix/function/function.hpp>
Phoenix 中的 function 可不是 boost 的泛型函数指针,它是用来帮助你实现 lazy function 的。把一个自己的函数实现成 lazy function 的主要好处就是,它可以和 Phoenix 的其它模块和谐共处。这个我们先按下不表,以后用到的时候,再详细解释。
Operator
#include <boost/spirit/home/phoenix/operator.hpp>
这个模块重载了几乎所有可以重载的 C++ 操作符,提供的当然是它们的 lazy 版本。事实上,正是由于有了这些 lazy operators,上一篇中这样的代码才成为可能:
std::generate(v.begin(), v.end(), ref(i)++)
std::for_each(v.begin(), v.end(), cout << arg1 << " ");
其中的 ++, << 都被解析为重载后的 lazy 版本。
Statement
#include <boost/spirit/home/phoenix/statement.hpp>
这个模块非常有趣,它提供了许多 C++ 语句,例如 if, else, while, switch, 甚至 try...catch 的 lazy 版本。可以说,它是在用 C++ 实现一个 lazy 版本的 C++!
这样说来比较抽象,我们看看一个例子:
输出:
Hi, young Amy
Hi, young Rose
Hello, Ralph
Hello, Zoe
Amy, enjoy your life!
Rose, enjoy your life!
Ralph, you stand by yourself.
Zoe, you know your fate.
使用 if_, else_, switch_,case_,我们大大拓展了 for_each 的用途,实现了一些相当复杂的循环。我们可以想象,把这些 lazy statement 和其他的那么多 STL 算法结合起来,可以发挥多大的威力。
Object
#include <boost/spirit/home/phoenix/object.hpp>
Object 模块包括7个组件,分别对应 C++ 的构造函数,new, delete, const_cast, static_cast, dynamic_cast 和 reinterprete_cast 的 lazy 版本。
还是看个例子,如果我们想要用 vector 建立一个数字金字塔,如下面的样子,那该怎么写呢?
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
6 6 6 6 6 6
7 7 7 7 7 7 7
8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9
10 10 10 10 10 10 10 10 10 10
上面的代码里,用来把 Matrix m 初始化成一个金字塔的代码只有一句:
generate(m.begin(), m.end(), construct<vector<int> >(ref(i)++, ref(i)));
其中的魔法是这样的:
ref(i) 每次都返回一个自增的 i,第一个成为 vector<int> 的元素个数,第二个成为初始值。
Bind
Phoenix 的 bind 和 boost.bind 差不多,但是更加健全些,我们在前面的 Statement 例子中已经用到过了。这里强调一下的是,它可以成功处理重载函数,在 Statement 例子里,bind 根据后面参数的个数,自动选择了正确的 greet 重载版本。