0

我有一个基类 Parameter 和两个派生类:Scalar 和 Vector。在每个派生类中,我都有一个成员函数,它以函数指针作为输入:

在标量类中:

typedef double (*samplerType)(RandNum& rnState);
void RegisterSampler( samplerType input );

在向量类中:

typedef std::vector<double> (*samplerType)(RandNum& rnState);
void RegisterSampler( samplerType input );

请注意不同的返回类型:doublestd::vector<double>. 我想在相互基类 Parameter 中定义这个函数——所以我更改了要使用的函数(void* input),然后在 Scalar 和 Vector 类中定义函数时尝试了以下操作:

samplerType inputSampler = dynamic_cast< samplerType >(input);

但是,我在 VS 2005 中收到以下错误:

error C2680: 'double (__cdecl *)(RandNum &)' : invalid target type for dynamic_cast
target type must be a pointer or reference to a defined class

Grumble Grumble Grumble... 我不确定这是否有效(标准允许)C++,但我想无论哪种方式我都会将其视为我设计中的缺陷。

所以,我的标准方法是使用函数的返回类型对基类进行模板化,但我不能。根据设计,基类 Parameter 必须不含所有类型信息。 是否有不同的方式来设计继承?

我对谷歌的尝试在函数指针上几乎没有出现——因此我相信这实际上是无效的语法,但也许只是一个非常非常不常见的设计挑战?这是另一个地方,救援的函子吗?

4

1 回答 1

1

除了 James 指出的设计缺陷之外,确实不能将函数指针转换为普通void*指针。但是,您可以在任意类型的函数指针之间进行转换(free-to-free,member-to-member):

typedef void (*samplerType)();
// in base class ...
samplerType sampler_;
template<class F>
void RegisterSampler(F sampler){
  // template so the user doesn't have to do the type cast
  sampler_ = reinterpret_cast<samplerType>(sampler);
}
// in derived class, where you access the sampler, you need to cast it back:
// (scalar)
typedef double (*realSamplerType)(RandNum& rnState);
// made-up function ...
void UseSampler(){
  realSamplerType sampler = reinterpret_cast<realSamplerType>(sampler_);
  double ret = sampler(param...);
}
于 2011-04-02T00:29:37.983 回答