function object研究之二

如何传递引用

<<Effective STL>>提到可以让function object继承自unary_function<T, void>,现在来试一下.

class B : public unary_function<int,void>{
public:
    B():x_(0){
    }

    void operator()(int x){
        cout<<++x_<<endl;
    }

    int x() const{
        return x_;
    }

private:
    int x_;

};

int main(int argc, char** argv) {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    A a;
    for_each(v.begin(),v.end(),a);
    cout<<a.x()<<endl;
    cout<<"------------"<<endl;
    B b;
    typedef vector<int>::iterator itor_type;
    for_each<itor_type,B&>(v.begin(),v.end(),b);
    cout<<b.x()<<endl;

    return 0;
}

现在看看unary_function的源代码,了解一下原理。

  template<typename _Arg, typename _Result>
    struct unary_function
    {
      /// @c argument_type is the type of the argument
      typedef _Arg      argument_type;

      /// @c result_type is the return type
      typedef _Result   result_type;
    };

这种方法虽然能解决问题,但是需要修改function object的源代码,而且要在使用for_each的时候显式的告知模板参数类型(回顾一下前一篇,for_each是一个模板函数,有两个模板参数),更多时候,我需要一种非侵入式的方式的简洁方式.
我在实际开发中解决方案之一是采用Pimple模式来处理,也就是B对象拥有一个指针p,指向具体的类,在operator()()中执行p->operator()()操作。Effective STL也提到,这样的好处就是还可一支持多态,而且避免在值传递的时候造成的对象切割。下面看看我自己的实现。

自己实现支持引用传递

前面Pimpl模式的解决方案可以给我们一个提示,如果我们有一个模板函数,能够将function object的地址作为指针保存在另一个类里面。这个新类也是一个function object,只不过它的operator()()内部简单转调真正的function object,即可。下面的代码是第一个简易版本。

template<typename function_object_type,typename element_type>
class function_object_ref{
public:
    explicit function_object_ref(function_object_type & object):object_(&object){

    }

    void operator()(element_type e){
        object_->operator()(e);
    }
private:
    function_object_type* object_;
};

int main(int argc, char** argv) {
    A a2;
    function_object_ref<A,int> wrapper(a2);
    for_each(v.begin(),v.end(),wrapper);
    cout<<a2.x()<<endl;
    return 0;
}

虽然还有提升空间,但是显然已经比unary_function的方案简单多了。


你可能感兴趣的:(object,function,iterator,each,wrapper)