Поэтому я не могу dynamic_cast <functionPointer>(((void *) (myFuncPtr)))? Что я должен делать? - PullRequest
0 голосов
/ 02 апреля 2011

У меня есть базовый класс, параметр и два производных класса: Scalar & Vector. В каждом производном классе у меня есть функция-член, которая принимает указатель функции в качестве входных данных:

В скалярном классе:

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

В классе Vector:

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

Обратите внимание на различные типы возврата: double и std::vector<double>. Я хотел бы определить эту функцию во взаимном базовом классе Parameter - поэтому я изменил функции на (void* input), а затем попробовал следующее при определении функций в классах Scalar & Vector:

samplerType inputSampler = dynamic_cast (входной);

Тем не менее, я получаю следующую ошибку в 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, должен - по замыслу - быть свободным от любой информации о типах. Есть ли другой способ оформления наследования?

Мои попытки Google это практически не дали указателям на функции - следовательно, я буду верить, что это на самом деле неверный синтаксис , но, возможно, просто действительно, действительно необычная проблема дизайна? Это еще одно из тех мест, функторы на помощь?

1 Ответ

1 голос
/ 02 апреля 2011

Помимо недостатка дизайна, на который указывает Джеймс, это правда, что вы не можете привести из функционального указателя к обычному 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...);
}
...