web-dev-qa-db-ja.com

関数が関数へのポインターを返すようにする方法は? (C ++)

文字を受け取り、その文字が何であるかに応じて関数へのポインターを返す関数を作成しようとしています。関数が関数へのポインタを返すようにする方法がわかりません。

63
user98188
#include <iostream>
using namespace std;

int f1() {
    return 1;
}

int f2() {
    return 2;
}

typedef int (*fptr)();


fptr f( char c ) {
    if ( c == '1' ) {
        return f1;
    }
    else {
        return f2;
    }
}

int main() {
    char c = '1';
    fptr fp = f( c );
    cout << fp() << endl;
}
68
anon
int f(char) {
    return 0;
}

int (*return_f())(char) {
    return f;
}

いいえ、真剣に、typedefを使用してください:)

95
erikkallen

関数シグネチャのtypedefを作成します。

typedef void (* FuncSig)(int param);

次に、FuncSigを返すように関数を宣言します。

FuncSig GetFunction();
17
sean e

C++ 11では、構文を単純化するために末尾の戻り値型を使用できます。関数を仮定する:

int c(int d) { return d * 2; }

これは関数から返すことができます(それを示すためにdoubleを受け取ります):

int (*foo(double e))(int)
{
    e;
    return c;
}

末尾の戻り型を使用すると、これは少し読みやすくなります。

auto foo2(double e) -> int(*)(int)
{
    e;
    return c;
}
4
Superfly Jon

関数を返すための構文:

return_type_of_returning_function (*function_name_which_returns_function)(actual_function_parameters) (returning_function_parameters)

例:次のように返される必要がある関数を考えます。

void* (iNeedToBeReturend)(double iNeedToBeReturend_par)
{
}

これで、iNeedToBeReturend関数を次のように返すことができます。

void* (*iAmGoingToReturn(int iAmGoingToReturn_par))(double)
{
   return iNeedToBeReturend;
}

私は、3年のプロのプログラミング生活の後にこの概念を学ぶのは非常に悪いと感じました。

関数ポインタの逆参照を待っているためのボーナス。

C++インタビューの質問

関数ポインタを返す関数の例は c ++の動的ライブラリのdlopen です

4

Typedefを使用せずにこれを行う方法は次のとおりです。

int c(){ return 0; }

int (* foo (void))(){  //compiles
return c;
}
4
user2875784
typedef void (*voidFn)();

void foo()
{
}

voidFn goo(char c)
{
    if (c == 'f') {
        return foo;
    }
    else {
        //..
    }
    // ..
}
4
ralphtheninja

このサイトをご覧ください- http://cdecl.org

英語からC宣言への変換、およびその逆変換を支援します!

クール!

このリンクは、erikallenの回答の例をデコードしています。 int(* return_f())(char)

2
m-sharp

これは、関数ポインターの戻りを示すコードです。最初に戻るには、「関数シグネチャ」を定義する必要があります。

int returnsOne() {
     return 1;
}

typedef int(*fp)();

fp returnsFPtoReturnsOne() {
    &returnsOne;
}

特定の場合:

fp getFunctionFor(char code) {
    switch (code) {
        case 'a': return &functionA;
        case 'b': return &functionB;
    }
    return NULL;
}
2
Thomas Jung

int f(char)ret_fを返す&fを想定しています。

C++ 98/C++ 03互換性のある方法:

  • Glyい方法:

    int (*ret_f()) (char) { return &f; }
    
  • Typedefを使用

    typedef int(sig)(char);

    sig * ret_f(){return&f; }

または

typedef int (*sig_ptr)(char);

sig_ptr ret_f() { return &f; }

C++ 11以降、さらに次のものがあります。

  • 末尾の戻り型:

    auto ret_f() -> int(*)(char) { return &f; }
    

    または

    auto ret_f() -> decltype(&f) { return &f; }
    
  • typedef with using

    using sig = int(char);
    
    sig* ret_f() { return &f; }
    

    または

    using sig_ptr = int (*)(char);
    
    sig_ptr ret_f() { return &f; }
    

C++ 14の追加:

  • auto控除:

    auto ret_f() { return &f; }
    
1
Jarod42

最も簡単な方法は、必要な関数へのポインタ型をtypedefし、それを使用することです

typedef void (*fnptr_t)(int, int);
fptr_t myfunc(char *) { ....
1
Chris Dodd

オブジェクトを返し、operator()を呼び出します。このようにして、関数はインターフェイスを返すことができ、すべてのクラスはこれを継承できます。つまり、CではなくC++を使用している場合です。

次に、パラメーター化されたファクターメソッドを使用して、入力に基づいてオブジェクトを返すことができます。

1
stefaanv

このようなもの

#include <iostream>

typedef char (*fn_ptr_t)(char);

char a_fn(char c)
{
  return c + 1;
}

char b_fn(char c)
{
  return c + 2;
}

fn_ptr_t
return_function(char c)
{
  fn_ptr_t result = 0;

  switch (c)
 {
    case 'a':
      result = a_fn;
      break;
    case 'b':
      result = b_fn;
      break;
 }

 return result;
}

int
main()
{
  fn_ptr_t fn = return_function('a');

  std::cout << "a(l) = " << (fn)('l') << std::endl;

  return 0;
}
0
Beano