Actor
Actor 是整個 Phoenix 的核心,幾乎所有的組件事實上都是 Actor。但是這個處於中心地位的組件,其實是一個很簡單的 concept:Actor 就是一個functor,它接受0~N個參數。
template <typename Eval><br />struct actor : Eval<br />{<br /> return_type<br /> operator()() const;<br /> template <typename T0><br /> return_type<br /> operator()(T0& _0) const;<br /> template <typename T0, typename T1><br /> return_type<br /> operator()(T0& _0, T1& _1) const;<br /> //...<br />};
actor 的模板參數,Eval,給 actor 提供了特例化的行為。下面我們會看到,其餘的 Phoenix 組件是如何在 actor 的基礎上,建立起一座優美的建築的。
Arguments
#include <boost/spirit/home/phoenix/core/argument.hpp>
Phoenix 的 Arguments 就是預留位置,它們就像一個個資料“桶”,我們可以把資料放在裡面,當作函數的參數來傳遞。它們的類型其實是:
actor<argument<N> >
N 代表第 N 個參數。Phoenix 已經預定義了幾個參數預留位置:
actor<argument<0> > const arg1 = argument<0>();
actor<argument<1> > const arg2 = argument<1>();
actor<argument<2> > const arg3 = argument<2>();
......
Values
#include <boost/spirit/home/phoenix/core/value.hpp>
Phoenix 的 value 是用來封裝常數的,當我們把一個常數6傳遞給一個 lazy function 的時候,它實際是封裝在一個 actor<value<int> > 對象裡面。所有 value 的類型都是
actor<value<T> >
其中 T 自然是常數的類型,在第一篇的例子中,已經使用過類似 val(3) 這樣的運算式,實際上 val 就會產生一個 actor<value<T> > 對象。
References
#include <boost/spirit/home/phoenix/core/reference.hpp>
Value 是封裝常量的,如果要封裝變數的引用,就要用到 reference,不用說,它們的類型是
actor<reference<T> >
T 仍然是變數的類型。這個模組在前面沒有詳細的例子,請看下面代碼:
#include <iostream><br />#include <vector><br />#include <algorithm><br />#include <boost/spirit/home/phoenix/core.hpp><br />#include <boost/spirit/home/phoenix/operator.hpp><br />using namespace std;<br />using namespace boost::phoenix;<br />using namespace boost::phoenix::arg_names;<br />int main()<br />{<br /> vector<int> v(10);<br /> int i = 1;<br /> std::generate(v.begin(), v.end(), ref(i)++);<br /> std::for_each(v.begin(), v.end(), cout << arg1 << " ");<br /> return 0;<br />}<br />
輸出:
1 2 3 4 5 6 7 8 9 10
在 std::generate(v.begin(), v.end(), ref(i)++) 這一行,每一次 ref(i)++ 被調用時,它除了返回 i 的當前引用,還真正對 i 的引用做自增操作,這樣 i 的值會不斷增加,從而把個等差數列填入 v。