Boost Phoenix 入门 (1)

Phoenix 可以看作是对 Boost Lambda Library 的重新实现。它是作为 Boost.Spirit 的一部分的,但是我们完全可以把它作为单独的库来使用,以达到一些非常酷和方便的效果。

 

基本上,Phoenix 大大方便了在 C++ 中进行 functional programming。当然,由于 C++ 不是函数式语言,我们没有可能进行严格的 functional programming,库的作用也只是让这种风格得到更方便的实现。在 STL 里,我们已经在进行一些 FP,例如对 functor 的利用使得算法的重用性大大提高,而 Phoenix 则让编写 functor 更加自然和简便。

 

val

在下面的代码中,val(3) 和 val("Hello Phoenix") 都是 functor,它们的作用就是返回它们的参数。而且,它们是 lazily evaluated 的。

 

#include <iostream> #include <boost/spirit/include/phoenix_core.hpp> using namespace std; using namespace boost::phoenix; int main() { cout << val(3)() << endl; cout << val("Hello Phoenix")() << endl; return 0; }  

输出:

3
Hello Phoenix

 

ref

val 返回的是对参数的复制,但有时候我们需要返回的是引用,这时可以使用 ref:

 

#include <iostream> #include <boost/spirit/include/phoenix_core.hpp> using namespace boost::phoenix; using namespace std; int main() { int i = 3; char const* s = "Hello Phoenix"; cout << ref(i)() << endl; cout << ref(s)() << endl; return 0; } 

输出与上面相同。

 

使用 lazy functor

这两个例子显得有点太无趣了,lazy evalution 的好处在于,一个 functor 可以被保存起来以后再用,因此也可以“插入”到已有的算法当中。所以,如果你写了一个 print 算法,那这些 functor 就有用了:

 

#include <iostream> #include <boost/spirit/include/phoenix_core.hpp> using namespace std; using namespace boost::phoenix; template <typename F> void print(F f) { cout << f() << endl; } int main() { print(val(3)); print(val("Hello Phoenix")); return 0; }   

输出结果与上面相同。

 

arg

在 Boost Lambda Library 中, 有几个叫做 _1, _2, _3... 之类的好东西,它们可以代替第 n 个参数,例如 _2 就返回第2个参数。Phoenix 原本也是这么命名的,但是现在改成了 arg1, arg2, arg3...,它们都位于 boost::phoenix::arg_names 命名空间。看下面程序:

 

#include <iostream> #include <boost/spirit/include/phoenix_core.hpp> using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace std; int main() { int i = 3; char const* s = "Hello Phoenix"; cout << arg1(i) << endl; cout << arg2(i, s) << endl; return 0; } 

输出仍然和上面相同。

 

来点有用的

下面这个例子比较有用,它去掉一个 vector 中所有的奇数,并且把结果打印出来。其中 remove_if 和 for_each 都是 STL 算法,它们都接受 functor,可以看到 Phoenix 让编写这些 functor 变得非常容易且直观。

 

#include <vector> #include <algorithm> #include <iostream> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace std; int main() { int init[] = {2, 10, 4, 5, 6, 1, 3, 9, 8, 7}; vector<int> c(init, init + 10); typedef vector<int>::iterator iterator; iterator cend = remove_if(c.begin(), c.end(), arg1 % 2 == 1); for_each(c.begin(), cend, cout << arg1 << " "); return 0; }  

输出:

2 10 4 6 8 

 

 

你可能感兴趣的:(算法,vector,iterator,lambda,library,functor)