基于变量输入的泛型类方法计算

时间:2017-03-01 12:05:37

标签: c++ design-patterns generic-programming

我大致得到了以下设置:

#include <iostream>
using namespace std;

template<typename T>
class Element{
    T getX() const;
    T getY() const;
 private:
    T x,y;
    std::vector<float> handling_times;
    float cost;
};

template<typename T, typename Tnext>
class Bloc {
     T getX() const;
     T getY() const;
 private:
     T x,y;
     Tnext num_blocs;
     float effort;
     float damage_done;
};

template<typename T>
class Measurements {
void calcMeasurements(const std::vector<T*> &data);
     float getMean() const;
 private:
     float mean;
};


int main() {
     std::vector<Element<int>*> elements;
     // fill with elements
     std::vector<Bloc<float,2>*> blocs;
     // fill with blocs

     // calculate mean of blocs effort
     Measurements<Bloc<float,1>> bloc_mean_effort_measurement;
     bloc_mean_effort_measurement.calcMeasurements(blocs);

     return 0;
 }

这两个类ElementBloc包含了一些我希望执行Measurements的数据。例如,我想衡量getMean() Element handling_times类型std::vector<float>的{​​{1}}。另一种情况是根据每个std::vector<Bloc<float>*> blocs中存储的工作量来衡量Bloc的平均值。正如您所看到的Measurement的输入类型不同,但平均计算背后的功能始终保持不变。我希望这个功能只实现一次(意思是我能想到的最简单的例子)并在不同类型上使用它。此外,我无法理解,如何根据哪个实体传递Measurement对象(例如Element costsBloc effort )应该计算量度。使用enum PossibleMeasurementsElementHANDLING_TIMESCOSTS是否有意义。因此,对于每个私有变量,我希望能够计算度量。

1 个答案:

答案 0 :(得分:0)

如果我理解了相关的问题,那么你或多或少都会这样:

struct A {
        std::vector<int> a;
};

struct B {
        int value;
        B(int x) : value(x) {}
};    
typedef std::vector<B> Bvect;

现在您想要计算具有相同泛型函数的值的平均值,无论它们是A还是Bvect。此通用函数已存在,称为std::accumulate。对于包含矢量的对象,您可以

A foo;
foo.a.push_back(123);
std::cout << std::accumulate(foo.a.begin(),foo.a.end(),0.0) << "\n";

您必须传递两个迭代器,指示要累积的最后一个元素的第一个和一个,以及一个初始值。

对于Bvect它看起来非常相似,我们只需提供一种自定义方式来添加元素:

Bvect b;
b.push_back(B(123));
std::cout << std::accumulate(b.begin(),
                             b.end(),
                             B(0),
                             [](B b1,B b2){
                                return B(b1.value + b2.value);
                             }).value << "\n";

我使用lambda来访问要添加的值,并构造一个B来保存两个值的总和。

PS:这个例子只计算总和,得到平均值只是除以元素数。