C++是否可以使用通用函数指针?

jte*_*dit 7 c++ generics pointers function

在C++中是否可以制作某种通用函数指针,指向任何返回指向某种类型的指针并且不带参数的函数?

例如,一种指针可以指向以下两种情况:

int* funcInt(){
    int* i = new int;
    *i = 5;
    return i;
}

char* funcChar(){
    char* c = new char;
    *c = 'a';
    return c;
}
Run Code Online (Sandbox Code Playgroud)

显然以下是有效的:

int* (*funcPointerA)() = funcInt;
char* (*funcPointerB)() = funcChar;
Run Code Online (Sandbox Code Playgroud)

但是有可能做类似下面的事情(它现在给出了编译错误):

void* (*funcPointerC)() = funcInt;
void* (*funcPointerD)() = funcChar;
Run Code Online (Sandbox Code Playgroud)

目前上面的代码给出了以下错误:

error: invalid conversion from 'int* (*)()' to 'void* (*)()'
error: invalid conversion from 'char* (*)()' to 'void* (*)()'
Run Code Online (Sandbox Code Playgroud)

有没有办法将funcPointerA和B转换为C和D?

这是指向两种类型的函数(以及其他在不带参数的情况下返回指向某种类型的指针)的指针可以一起存储在单个向量中.

Jon*_*ely 9

有没有办法将funcPointerA和B转换为C和D?

是的,您可以显式地将一种类型的函数指针转换为另一种类型:

void* (*funcPointerC)() = reinterpret_cast<void*(*)()>(funcInt);
Run Code Online (Sandbox Code Playgroud)

但是调用强制转换结果是未定义的行为,必须先将其强制转换回原始类型.如果您可以记录原始类型并安排将指针强制转换回原始类型,那么您的代码可以正常工作.


n. *_* m. 8

标准不允许这样的事情.您可能会或可能无法将函数指针转换为void* (*)().在C++中,有符合标准的解决方案.这是一个简单的pre-C++ 11之一:

struct MyFunc
{
  virtual void* operator()() = 0;
  virtual ~Myfunc(){}
};

template <typename T>
struct MyfuncImpl
{
  typedef T TFunc();
  MyfuncImpl (TFunc* func) : m_func(func) {}
  void* operator()() { return m_func(); }
 private:
  TFunc* m_func;
};
Run Code Online (Sandbox Code Playgroud)

现在您可以存储shared_ptr<Myfunc>在矢量中.

C++ 11中更好的解决方案可能如下所示:

template <typename T>
std::function<void*()> castToVoidFunc (T* (*func)())
{
  return [=](){ return func(); };
}
Run Code Online (Sandbox Code Playgroud)

  • 标准_does_允许转换函数指针,参见[expr.reinterpret.cast]/6,它只是不允许在转换后调用它们.你的C++ 11解决方案中的lambda是不必要的,如果存在隐式转换序列,`std :: function <R()>`会将返回值转换为`R`,所以你可以只返回std :: function <无效*()>(FUNC);` (2认同)