12 Stimmen

Ist es möglich in C oder C++, eine Funktion innerhalb einer anderen Funktion zu erstellen?

Könnte mir jemand bitte sagen, ob dies in C oder C++ möglich ist?

void fun_a();
//int fun_b();
...
main(){
   ...
   fun_a();
   ...
   int fun_b(){
     ...
   }
   ...
} 

oder etwas Ähnliches, wie z.B. eine Klasse innerhalb einer Funktion?

Vielen Dank für eure Antworten,

4voto

I. J. Kennedy Punkte 23203

Der Begriff, den Sie suchen, lautet geschachtelte Funktion. Weder Standard-C noch C ++ erlauben geschachtelte Funktionen, aber GNU C erlaubt es als Erweiterung. Hier ist ein guter Wikipedia-Artikel zum Thema.

3voto

Robert Karl Punkte 7499

Clang/Apple arbeiten an 'Blocks', anonymen Funktionen in C! :-D

^ ( void ) { printf("hello world\n"); }

Informationen hier und hier Spezifikation, und ars technica hat ein bisschen darüber

3voto

Mr Fooz Punkte 102791

Nein, und es gibt mindestens einen Grund, warum es die Dinge komplizieren würde, dies zuzulassen. Verschachtelte Funktionen haben in der Regel Zugriff auf den umgebenden Bereich. Dadurch kann der "Stack" nicht mehr mit einer Stapel-Datenstruktur dargestellt werden. Stattdessen wird ein vollständiger Baum benötigt.

Betrachten Sie den folgenden Code, der tatsächlich in gcc kompiliert, wie KennyTM vorschlägt.

#include 

typedef double (*retdouble)();

retdouble wrapper(double a) {
  double square() { return a * a; }

  return square;
}

int use_stack_frame(double b) {
  return (int)b;
}

int main(int argc, char** argv) {
  retdouble square = wrapper(3);
  printf("Erwarte  9 tatsächlich %f\n", square());
  printf("Erwarte  3 tatsächlich %d\n", use_stack_frame(3));
  printf("Erwarte 16 tatsächlich %f\n", wrapper(4)());
  printf("Erwarte  9 tatsächlich %f\n", square());
  return 0;
}

Ich habe das platziert, was die meisten Leute erwarten würden, gedruckt zu werden, aber tatsächlich wird Folgendes gedruckt:

Erwarte  9 tatsächlich 9.000000
Erwarte  3 tatsächlich 3
Erwarte 16 tatsächlich 16.000000
Erwarte  9 tatsächlich 16.000000

Beachten Sie, dass die letzte Zeile die Funktion "square" aufruft, aber der Wert "a", auf den zugegriffen wird, wurde während des Aufrufs von "wrapper(4)" geändert. Dies liegt daran, dass für jede Instanz von "wrapper" kein separater "Stack"-Rahmen erstellt wird.

Beachten Sie, dass diese Art von verschachtelten Funktionen in anderen Sprachen, die sie unterstützen, wie Lisp und Python (und sogar in neueren Versionen von Matlab), tatsächlich ziemlich häufig sind. Sie führen zu sehr leistungsstarken funktionalen Programmierfähigkeiten, schließen jedoch die Verwendung eines Stacks zur Aufnahme lokaler Bereichsrahmen aus.

3voto

MSN Punkte 51308
void foo()
{
    class local_to_foo
    {
        public: static void another_foo()
        { printf("whatevs"); }
    };
    local_to_foo::another_foo();
}

Oder Lambda's in C++0x.

2voto

Josh Townzen Punkte 1328

Sie können eine lokale Klasse innerhalb einer Funktion verschachteln, in diesem Fall ist die Klasse nur für diese Funktion zugänglich. Sie könnten dann Ihre verschachtelte Funktion als Mitglied der lokalen Klasse schreiben:

#include 

int f()
{
    class G
    {
    public:
        int operator()()
        {
            return 1;
        }
    } g;

    return g();
}

int main()
{
    std::cout << f() << std::endl;
}

Bedenken Sie jedoch, dass Sie eine in einer lokalen Klasse definierte Funktion nicht an einen STL-Algorithmus wie sort() übergeben können.

int f()
{
    class G
    {
    public:
        bool operator()(int i, int j)
        {
            return false;
        }
    } g;

    std::vector v;

    std::sort(v.begin(), v.end(), g);  // Kompiliert nicht
}

Der Fehler, den Sie von gcc erhalten würden, lautet "test.cpp:18: Fehler: keine übereinstimmende Funktion für den Aufruf von `sort(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, f()::G&)' "

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X