抽象调用以组合类向量的结果

时间:2014-11-25 18:58:18

标签: c++ c++11

我有一个类,它充当指向抽象基类的指针向量的组合。在组合类中,有很多重复的函数用于将成员函数组合在一起,例如。

class Base {
public:
    virtual double foo1(double x) = 0;
    virtual double foo2(double x) = 0;
};

class Combined : public Base {
    std::vector< std::shared_ptr<Base> > bases;

public:
    double foo1(double x) {
        double rv = 0.0;
        for( auto& b : bases ) {
            rv += b->foo1(x);
        }
        return rv;
    }

    double foo2(double x) {
        double rv = 0.0;
        for( auto& b : bases ) {
            rv += b->foo2(x);
        }
        return rv;
    }
};

感觉我应该能够编写一个函数来抽象该模式而不必为每个方法重复它,因此Combined可以用诸如

之类的方式编写
class Combined : public Base {
    std::vector< std::shared_ptr<Base> > bases;

public:
    double foo1(double x) {
        return combiner(foo1, x);
    }

    double foo2(double x) {
        return combiner(foo2, x);
    }
};

并且会有

的组合函数
double combiner(FuncName f, double x)
{
    double rv = 0.0;
    for( auto& b : bases ) {
        rv += b->f(x);
    }
    return rv;
}

减少样板数量

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:6)

它被称为std::accumulate(在<numeric>中找到),它可以做到这一点。

答案 1 :(得分:1)

    #include <iostream>
    #include <memory>
    #include <algorithm>

    using namespace std;

    struct iFoo {virtual double foo() const=0;};
    struct A : public iFoo {virtual double foo() const{return 10;}};
    struct B :  public iFoo {virtual double foo() const{return 20;}};

    std::vector<std::unique_ptr<iFoo>> foos;//pretend its a member variable i'm lazy

    //pretend its a member function (again, lazy)
    template <typename T,typename K>
    T xform_accumulate(T init,K xformer)
    {
        return std::accumulate(foos.cbegin(),foos.cend(),init,[xformer](T a,const std::unique_ptr<iFoo>& b) {return a+xformer(b);});
    }


    int main()
    {

        foos.push_back(std::unique_ptr<iFoo>(new A()));
        foos.push_back(std::unique_ptr<iFoo>(new B()));

        double x = xform_accumulate( 0.0, [](const std::unique_ptr<iFoo>& x){return x->foo();});

       cout << "Hello World" << x << endl; 

       return 0;
    }