it-swarm.com.de

Funktionszeigertyp zurückgeben

Oft finde ich die Notwendigkeit, Funktionen zu schreiben, die Funktionszeiger zurückgeben. Wenn ich das mache, ist das grundlegende Format, das ich verwende:

typedef int (*function_type)(int,int);

function_type getFunc()
{
   function_type test;
   test /* = ...*/;
   return test;
}

Dies kann jedoch bei einer großen Anzahl von Funktionen umständlich werden, so dass ich nicht für jede einzelne (oder für jede Klasse von Funktionen) ein Typedef deklarieren muss.

Ich kann das typedef entfernen und die in der Funktion zurückgegebene lokale Variable als: int (*test)(int a, int b); deklarieren, damit der Funktionskörper wie folgt aussieht:

{
     int (*test)(int a, int b);
     test /* = ...*/;
     return test;
}

aber dann weiß ich nicht, was ich für den Rückgabetyp der Funktion einstellen soll .. Ich habe es versucht:

int(*)(int,int) getFunc()
{
    int (*test)(int a, int b);
    test /* = ...*/;
    return test;
}

aber das meldet einen Syntaxfehler. Wie deklariere ich den Rückgabetyp für eine solche Funktion, ohne einen Typedef für den Funktionszeiger zu deklarieren? Ist es überhaupt möglich? Beachten Sie auch, dass mir bewusst ist, dass es anscheinend sauberer wäre, Typedefs zu deklarieren. Für jede der Funktionen bin ich jedoch sehr darauf bedacht, meinen Code so zu strukturieren, dass er so sauber und einfach wie möglich ist. Der Grund, weshalb ich die Typedefs entfernen möchte, ist, dass sie häufig nur zur Deklaration der Retrieval-Funktionen verwendet werden und daher im Code überflüssig erscheinen.

46
S E
int (*getFunc())(int, int) { … }

Dies liefert die von Ihnen angeforderte Erklärung. Als ola1olsson notes wäre es außerdem gut, void einzufügen:

int (*getFunc(void))(int, int) { … }

Dies besagt, dass getFunc keine Parameter übernehmen darf, wodurch Fehler vermieden werden können, z. B. wenn jemand versehentlich getFunc(x, y) anstelle von getFunc()(x, y) schreibt.

53

Sie können wahrscheinlich so etwas tun:

int foo (char i) {return i*2;}

int (*return_foo()) (char c)
{
   return foo;
}

aber Gott, ich hoffe, ich werde nie Code debuggen müssen ....

5
yosim

ich lass das hier, da es etwas kniffeliger war als die bereits gegebenen Antworten, da es einen Funktionszeiger erfordert 

(int (__cdecl *)(const char *)) 

und gibt einen Funktionszeiger zurück

(int (__cdecl *)(const char *))

#include <stdio.h>

int (*idputs(int (*puts)(const char *)))(const char *) {
    return puts;
}

int main(int argc, char **argv)
{
    idputs(puts)("Hey!");

    return 0;
}
2
Dmitry

Während ich C-Code in C++ - Klassen einbaute, hatte ich den gleichen Wunsch wie das ursprüngliche Poster: Einen Funktionszeiger aus einer Funktion zurückgeben, ohne auf den Funktionszeiger-Prototyp typedef zurückzugreifen. Ich habe ein Problem mit der C++ - const - Korrektheit entdeckt, von dem ich dachte, dass sie es wert ist, geteilt zu werden, auch wenn sie ein wenig vom Thema abweicht (C++), aber sie bezieht sich direkt auf die ursprüngliche Frage: Die Syntax für die Rückgabe eines C-Funktionszeigers ohne Rückgriff auf eine typedef.

Der folgende Code definiert eine Klasse A, in der ein Funktionszeiger gespeichert und durch den Aufruf get_f() der Außenwelt zugänglich gemacht wird. Dies ist die Funktion, die einen Funktionszeiger ohne typedef zurückgeben soll.

Der Punkt (der mich für einige Zeit verblüffte) war, wie man erklärt, dass get_f() eine const - Funktion ist, d. H., Sie würde A nicht ändern.

Der Code enthält 2 Varianten: Die erste verwendet ein typedef für den Funktionszeiger-Prototyp, während die zweite alles vollständig ausschreibt. Das #if wechselt zwischen den beiden.

#include <iostream>

int my_f(int i)
{
  return i + 1;
}

#if 0 // The version using a typedef'ed function pointer

typedef int (*func_t)(int);

class A
{
public:
  A(func_t f) : m_f(f) {}
  func_t get_f() const { return m_f; }

private:
  func_t m_f;
};

int main(int argc, char *argv[])
{
  const A a(my_f);
  std::cout << "result = " << a.get_f()(2) << std::endl;
}

#else // The version using explicitly prototyped function pointer    

class A
{
public:
  A(int (*f)(int)) : m_f(f) {}
  int (*get_f() const)(int) { return m_f; }

private:
  int (*m_f)(int);
};

int main(int argc, char *argv[])
{
  const A a(my_f);
  std::cout << "result = " << a.get_f()(2) << std::endl;
}

#endif

Die erwartete/gewünschte Ausgabe ist:

result = 3

Der Schlüsselpunkt ist die Position des Qualifiers const in der Zeile:

int (*get_f() const)(int) { return m_f; }
1
duncan

Dies ist ein dummes Beispiel, aber es ist einfach und es gibt keine Fehler. Es geht nur darum, statische Funktionen zu deklarieren:

#include <stdio.h>
#include <stdlib.h>

void * asdf(int);
static int * hjkl(char,float);

main() {
  int a = 0;
  asdf(a);
 }


void * asdf(int a) {return (void *)hjkl; }
static int * hjkl(char a, float b) {int * c; return c;}
1
NicoM

Sie können den folgenden Code schreiben (funktioniert nur in C++ 11 und höher):

//C++11
auto func(...) {
    int (*fptr)(...) ret = ...
    //Do sth.
    return ret;//C++11 compiler will automatically deduce the return type for you
}

Wenn Sie den automatischen Abzugstyp nicht mögen, können Sie den Typ am Ende der Funktion angeben.

//C++11
auto func(...) -> int (*)(...) { /* Do sth. */ }
0
JiaHao Xu

Ich denke, du hast drei Möglichkeiten:

  1. Bleib bei Typedef. Am Ende des Tages ist es die Aufgabe von Typedef. 
  2. Geben Sie void * und das Casting zurück.
  3. Überdenken Sie Ihre Softwarearchitektur. Vielleicht können Sie uns mitteilen, was Sie erreichen wollen und ob wir Sie in eine bessere Richtung weisen können.
0
Raffaele Rossi