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

Generic class method computation based on variable input

我大致得到了以下设置:

#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 的数据。例如,我想测量类型为 std::vector<float>Elementhandling_timesgetMean()。另一种情况是根据每个 Bloc 中存储的工作量来衡量 std::vector<Bloc<float>*> blocs 的平均值。如您所见,Measurement 的输入类型各不相同,但均值计算背后的功能始终保持不变。我希望这个功能只实现一次(mean 只是我能想到的最简单的例子)并在不同类型上使用它。此外,我无法理解如何根据哪个实体(例如 Element costsBloc effort)传递 Measurement 对象应计算测量值。在 ElementHANDLING_TIMESCOSTS 中有一个 enum PossibleMeasurements 有意义吗?所以说对于每个私有变量,我希望能够计算其上的度量。

如果我正确理解问题,你或多或少是这样的:

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:本例只求和,求平均值只需除以元素个数即可。