【发布时间】:2014-07-30 17:02:31
【问题描述】:
我正在编写一个可以在不同模式下实例化的类。一个简单的案例也许 一个平均计算机,可以根据模式计算不同类型的平均值。
该类将由其他一些代码实例化,并且该类代码将通过函数指针通用。必须根据模式定义与不同模式关联的特定功能并设置指针。
我的样子是这样的
enum StatMode { EMA, SMA} ;
class MeanComputer {
public:
MeanComputer ();
MeanComputer (const MeanComputer& orig);
virtual ~MeanComputer();
template <StatMode> double Update (double x);
template <StatMode> double Sample (double x);
void Reset();
void setFunction() {
if (mode == EMA ) do_calc = /*EMA mode function*/ ;
}
double (MeanComputer::*do_calc)(double);
private:
std::vector <double> window ;
double mean ;
double variance ;
StatMode mode;
};
template <StatMode SMA> double MeanComputer::Update(double x) {
}
template <StatMode EMA> double MeanComputer::Update(double x) {
}
但是这似乎没有编译并给出错误 错误:没有匹配函数调用 'MeanComputer::Update(double&)'
我该如何进行这项工作。 我理解一种方法是让每个这样的模式函数由不同的名称定义,并设置 然后是函数指针。虽然这似乎需要太多的命名,并且具有更简洁的模式模板功能似乎更优雅且更易于理解。
更新: 计算的方法不是在编译时设置的,而是在运行时设置的。但是,对于类的给定对象,模式保持不变,因此相应地设置指针将一劳永逸。 虚拟基类也可以,但在实际情况下,很多计算都是通用的, 并且只有一些特定或小的功能取决于模式。一个人为的例子可能是平均计算机更新某种坐标对象,它采用一对模式类型,SMA/EMA 和纬度/经度。因此,一个实例可能是经度平均值,而另一个实例是纬度平均值。完整的计算是相同的,只是一个读取不同的成员。
【问题讨论】:
-
为什么不将枚举作为函数参数传递呢?为什么计算均值的方法需要在编译时设置?
-
@NeilKirk 因为它可以在编译时解决,而且switch语句很难看。
-
好吧,我想我用错了术语。计算的方法不是在编译时设置的,而是在运行时设置的。但是对于类的给定对象,模式保持不变。但是使用 switch 效率低下,而且肯定更容易出错。均值只是一个例子,还有更复杂的场景。意思似乎只是一个简单的案例
-
这既不优雅也不易于理解。这似乎正是实现基类和派生类以及确定要实例化哪个工厂的正确位置。
-
@Aggieboy 你对前者有多肯定,后者是意见。
标签: c++ templates enums function-pointers