程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> function object研究之list1分析

function object研究之list1分析

編輯:C++入門知識

首先看一下bind.hpp中的list0模板定義:

[cpp] 
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>是什麼?定義如下:

[cpp]  www.2cto.com
template<class T> class type {}; 
只是一個普通模板,接受任何類型。
2.unwrap(f,0)的結果是返回f, 因此如果f是以一個函數傳遞給了operator()(type<R>, F& f, A&, long) ,則內部的unwrap(f,0)返回的是f

因此實際上代碼被編譯成了直接調用f的代碼:f()

這是個很好的讓編譯器在編譯期產生調用函數代碼的技巧。

 因此功能比較強大。

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>繼承,
因此也就擁有了a1_, 這裡有點不明白,為什麼偏特化版本的storag1沒有定義a1_,只有a1()靜態函數,居然這裡就有了。下面的代碼編譯通過。

[cpp]
boost::_bi::storage1<boost::arg<1> > x(_1); 
x.a1_; 
2. 幾個operator[]() 函數有點意思,用_1作為下標,調用的是第一個重載:

[cpp] 
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模式的實現。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved