当前位置:编程学习 > C/C++ >>

function object研究之list1分析

首先看一下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.zzzyk.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模式的实现。


 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,