6

デフォルト値を持つパラメーターを持つ関数ポインターで動作する、オーバーロードされた関数を呼び出そうとしています。

void originalFunction1 (int a = 0) {printf("I'm #1 and a is %d",a);}
void originalFunction2 () {printf("I'm #2");}

void overloadedFunction (void (*fptr)(void))
{
  fptr();
}

void overloadedFunction (void (*fptr)(int))
{
  overloadedFunction( (void(*)(void)) fptr);
}

int main() 
{
  overloadedFunction(originalFunction1);
  overloadedFunction(originalFunction2);

  // output is:
  // I'm #1 an a is -1073743272
  // I'm #2
}

この質問への回答が指摘しているように、デフォルト値は関数シグネチャの一部ではなく、(関数ポインター -) パラメーター定義中に繰り返すこともできません。私の例が示すように、呼び出しのためにキャストすることはできますが、デフォルト値に初期化されることはありません。

これを回避する方法はありますか?

元の関数を変更することはできませんが、デフォルト値は知っています。メインのオーバーロードされた関数とリダイレクトの両方を変更できます。fptr は、常にパラメーターなしでのみ呼び出されます。実際には、戻り値の型も異なるため、オーバーロードされた関数はもっとありますが、より簡単にキャストできます。

4

1 に答える 1

2

短い答えはノーです。キャストは合法ですが、結果に対してできる唯一のことは、キャストを元の型に戻すことです。デフォルトの引数は、関数のシグネチャを変更しません。それらは、クライアントが引数を提供しない場合に渡される呼び出しサイトでのみアカウントに入ります。関数自体は常に引数の完全なセットで呼び出されますが、キャストの結果を介して呼び出す場合は明らかにそうではありません。

ここでの通常の答えは、ソースを制御できる場合、デフォルト引数の代わりにオーバーロードを使用することです。(デフォルト引数の代わりに常にオーバーロードを使用する必要があるという引数を聞いたことがあります。)

void originalFunction1( int a ) { ... }
void originalFunction1() { originalFunction1( 0 ); }

あなたが持っているものの代わりに。

または、テンプレートを使用してゲームをプレイできる場合があります。

template <typename FunctionPtr>
void overloadedFunction( FunctionPtr fptr )
{
    fptr();
}

ただし、使用できる場合は最初のソリューションをお勧めします。

于 2013-02-14T08:54:50.510 に答える