10

C++ では、何らかの型へのポインターを返し、引数を取らない関数を指す、ある種のジェネリック関数ポインターを作成することは可能ですか?

たとえば、次の両方を指すことができる 1 つのタイプのポインター:

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

char* funcChar(){
    char* c = new char;
    *c = 'a';
    return c;
}

明らかに、以下は有効です。

int* (*funcPointerA)() = funcInt;
char* (*funcPointerB)() = funcChar;

しかし、次のようなことは可能ですか (現時点ではコンパイル エラーが発生します)。

void* (*funcPointerC)() = funcInt;
void* (*funcPointerD)() = funcChar;

現在、上記のコードでは次のエラーが発生します。

error: invalid conversion from 'int* (*)()' to 'void* (*)()'
error: invalid conversion from 'char* (*)()' to 'void* (*)()'

funcPointerA と B を C と D にキャストする方法はありますか?

これは、両方のタイプの関数 (および引数を取らずに何らかのタイプへのポインターを返す他の関数) へのポインターを 1 つのベクトルにまとめて格納できるようにするためです。

4

2 に答える 2

8

規格では、そのようなことは許可されていません。関数ポインタを にキャストしても、うまくいかない場合がありますvoid* (*)()。C++ には、標準に準拠したソリューションがあります。これは単純な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;
};

shared_ptr<Myfunc>これで、ベクターに保存できます。

C++11 でのより優れたソリューションは、次のようになります。

template <typename T>
std::function<void*()> castToVoidFunc (T* (*func)())
{
  return [=](){ return func(); };
}
于 2013-05-12T15:41:52.913 に答える