基于变量输入的泛型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;
}
所以两个 类 Element
和 Bloc
保存了一些我想执行 Measurements
的数据。例如,我想测量类型为 std::vector<float>
的 Element
的 handling_times
的 getMean()
。另一种情况是根据每个 Bloc
中存储的工作量来衡量 std::vector<Bloc<float>*> blocs
的平均值。如您所见,Measurement
的输入类型各不相同,但均值计算背后的功能始终保持不变。我希望这个功能只实现一次(mean 只是我能想到的最简单的例子)并在不同类型上使用它。此外,我无法理解如何根据哪个实体(例如 Element
costs
或 Bloc
effort
)传递 Measurement
对象应计算测量值。在 Element
和 HANDLING_TIMES
和 COSTS
中有一个 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:本例只求和,求平均值只需除以元素个数即可。
我大致得到了以下设置:
#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;
}
所以两个 类 Element
和 Bloc
保存了一些我想执行 Measurements
的数据。例如,我想测量类型为 std::vector<float>
的 Element
的 handling_times
的 getMean()
。另一种情况是根据每个 Bloc
中存储的工作量来衡量 std::vector<Bloc<float>*> blocs
的平均值。如您所见,Measurement
的输入类型各不相同,但均值计算背后的功能始终保持不变。我希望这个功能只实现一次(mean 只是我能想到的最简单的例子)并在不同类型上使用它。此外,我无法理解如何根据哪个实体(例如 Element
costs
或 Bloc
effort
)传递 Measurement
对象应计算测量值。在 Element
和 HANDLING_TIMES
和 COSTS
中有一个 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:本例只求和,求平均值只需除以元素个数即可。