Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 所以我可以';t动态_cast<;函数指针>;(((void*)(myFuncPtr))?我该怎么办?_C++_Function Pointers_Dynamic Cast - Fatal编程技术网

C++ 所以我可以';t动态_cast<;函数指针>;(((void*)(myFuncPtr))?我该怎么办?

C++ 所以我可以';t动态_cast<;函数指针>;(((void*)(myFuncPtr))?我该怎么办?,c++,function-pointers,dynamic-cast,C++,Function Pointers,Dynamic Cast,我有一个基类、参数和两个派生类:标量和向量。在每个派生类中,我都有一个成员函数,它以函数指针作为输入: 在标量类中: typedef double (*samplerType)(RandNum& rnState); void RegisterSampler( samplerType input ); 在Vector类中: typedef std::vector<double> (*samplerType)(RandNum& rnState); void Regist

我有一个基类、参数和两个派生类:标量和向量。在每个派生类中,我都有一个成员函数,它以函数指针作为输入:

在标量类中:

typedef double (*samplerType)(RandNum& rnState);
void RegisterSampler( samplerType input );
在Vector类中:

typedef std::vector<double> (*samplerType)(RandNum& rnState);
void RegisterSampler( samplerType input );
发牢骚发牢骚。。。我不确定这是否是有效的(标准允许的)C++,但是我想无论哪种方式,我都会把它当作我设计中的一个缺陷。 因此,我的标准方法是用函数的返回类型模板化基类,但我不能。根据设计,基类Parameter必须没有所有类型信息是否有其他方法来设计继承?


我尝试用谷歌搜索它,结果发现函数指针几乎为零——因此我相信这实际上是无效的语法,但可能只是一个非常非常罕见的设计挑战这是另一个地方吗,要拯救的函子?

除了James指出的设计缺陷之外,确实不能将函数指针转换为正常的
void*
指针。但是,您可以在任意类型的函数指针之间强制转换(自由到自由,成员到成员):

typedef void(*sampletype)();
//在基类中。。。
采样器型采样器;
模板
空隙登记采样器(F采样器){
//这样用户就不必进行类型转换
取样器=重新解释铸件(取样器);
}
//在派生类中,在访问采样器的地方,需要将其回滚:
//(标量)
typedef double(*realSamplerType)(RandNum和rnState);
//虚构的功能。。。
真空采样器(){
realSamplerType取样器=重新解释(取样器);
双ret=取样器(参数…);
}

我不理解其基本原理:为什么希望这个无类型的
参数
成员位于基类中?您无法使用它,因为它的类型未知。函数对象帮不了你(除非你做了一些难看的事情,比如将它声明为返回一个
boost::any
),因为返回类型对于函数对象的类型是必不可少的。我不希望它出现在基类中,但我希望从基类指针访问注册函数。换句话说,我有一个参数*数组,我想注册一个函数,我知道它对给定的参数*有正确的签名。目的是什么?除非你知道它的实际类型,否则你不能使用它,根据你所说的,它依赖于派生类,对吧?在基类中有一个注册函数,它接受实际返回不同类型的函数(指针或对象),因为这种差异取决于子类,因此打破了多态性。是的,我有一个参数*,但我碰巧知道它的真正派生类型。我想在参数*上调用RegisterSampler,但我想我应该首先动态转换以避免整个错误。谢谢我刚刚尝试了这个,得到了:
错误C2440:'static_cast':无法从'Matrix(uu cdecl*)(RandNum&)'转换为'void(u cdecl*)(RandNum&)'UDT返回值的不兼容调用约定。
@M.Tibbits:让我检查一下。我刚刚发现,你所说的看起来很合理,有趣的阅读与你的观点一致--尽管你失去了类型安全性。。。类型安全?什么类型的安全?@M.Tibbits:我的错,你当然需要在那里重新解释一下。我有一个很差的习惯,只是使用C风格的铸件,所以我总是忘记什么时候使用哪个C++演员…@ @ TiBBIT:你甚至可以使用<代码> TyPufF D版本。这就是我在前面的评论中对C风格演员的意思。而且“void”函数指针不需要参数btw。除此之外,
dynamic_cast
仅用于指向结构/类对象的指针,从基对象到派生对象等等。
error C2680: 'double (__cdecl *)(RandNum &)' : invalid target type for dynamic_cast
target type must be a pointer or reference to a defined class
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...);
}