首先看一下bind.hpp中的list0模板定義:
class list0{public: list0() {} template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); } template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); } template<class R, class F, class A> R operator()(type<R>, F & f, A &, long) { return unwrapper<F>::unwrap(f, 0)(); } template<class R, class F, class A> R operator()(type<R>, F const & f, A &, long) const { return unwrapper<F const>::unwrap(f, 0)(); } template<class F, class A> void operator()(type<void>, F & f, A &, int) { unwrapper<F>::unwrap(f, 0)(); } template<class F, class A> void operator()(type<void>, F const & f, A &, int) const { unwrapper<F const>::unwrap(f, 0)(); } template<class V> void accept(V &) const { } bool operator==(list0 const &) const { return true; }};
提供了accept方法接受V&,但是什麼實現也沒有。提供了一堆operator重載函數,重點關注operator()()的函數,說明其實list0就是一個function object。
1.type<R>是什嗎?定義如下:
template<class T> class type {};
只是一個普通模板,接受任何類型。
2.unwrap(f,0)的結果是返回f, 因此如果f是以一個函數傳遞給了operator()(type<R>, F& f, A&, long) ,則內部的unwrap(f,0)返回的是f
因此實際上代碼被編譯成了直接調用f的代碼:f()
這是個很好的讓編譯器在編譯期產生調用函數代碼的技巧。
unwrap還接受另外兩種類型,參考:http://blog.csdn.net/sheismylife/article/details/8272615
因此功能比較強大。
3.實際上f函數執行的時候傳遞進來的參數這裡是空,下面就能看到有一個參數的例子。
繼續看list1的定義:
template< class A1 > class list1: private storage1< A1 >{private: typedef storage1< A1 > base_type;public: explicit list1( A1 a1 ): base_type( a1 ) {} A1 operator[] (boost::arg<1>) const { return base_type::a1_; } A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); } template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); } template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); } template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long) { return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]); } template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const { return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_]); } template<class F, class A> void operator()(type<void>, F & f, A & a, int) { unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]); } template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const { unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_]); } template<class V> void accept(V & v) const { base_type::accept(v); } bool operator==(list1 const & rhs) const { return ref_compare(base_type::a1_, rhs.a1_, 0); }};
看到很多老朋友了吧?
1.從storage1<A1>繼承,回顧前面的文章:http://blog.csdn.net/sheismylife/article/details/8269153
因此也就擁有了a1_, 這裡有點不明白,為什麼偏特化版本的storag1沒有定義a1_,只有a1()靜態函數,居然這裡就有了。下面的代碼編譯通過。
boost::_bi::storage1<boost::arg<1> > x(_1); x.a1_;
2. 幾個operator[]() 函數有點意思,用_1作為下標,調用的是第一個重載:
list[_1];-->A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
3.operator()()函數的參數A & a實際上也是一個list1<A1 &>對象,並且裡面的a_成員就是外部實際調用的參數。
a[base_type::a1_] 這句代碼要注意:
通過this對象的base_type::a1_,這時候a1_是指標函數,返回預留位置boost::arg<1> 。
用a1_來作為參數,傳遞給a對象的operator[](boost::arg<1> (*)() 方法來擷取內部儲存的實際參數。
a對象和this對象都是一個從模板list1<>演化而來,但是不是同一個對象。
4.其他的函數都比較簡單, accept以前也介紹過,visitor模式的實現。