2015-09-12 12 views
7

Heute stieß ich auf this Stück Code:prototypisiert Funktion von structs

int main() { 
    struct Foo {}; 
    struct Bar {}; 

    Foo(b)(int (Bar*c)); // ? 

    return 0; 
} 

Ich habe absolut keine Ahnung, was los ist. Mein Compiler (VC14) warnt mich vor einer ungenutzten Prototyp-Funktion?

Was diese Linie zu tun hat (eine Funktion erklären: die Namen, welche Parameter und Rückgabetyp Wie es nennen?)

Foo(b)(int (Bar*c)); 

Vielen Dank im Voraus für das Helfen ich heraus!

Antwort

6

Dies erklärt, eine Funktion, die aufgerufen b:

  • nimmt int (Bar*c) als Argument;
  • gibt Foo zurück.

Der Typ des Arguments, int (Bar*c), ist ein Zeiger auf eine Funktion, die einen Zeiger auf Bar nimmt und gibt eine int. Hier ist c der Name des Arguments und kann weggelassen werden: int (Bar*).

Hier ist, wie Sie b anrufen:

int main() { 
    struct Foo {}; 
    struct Bar {}; 

    Foo(b)(int (Bar* c)); // the prototype in question 

    int func(Bar*);  // a function defined elsewhere 
    Foo result = b(func); 

    return 0; 
} 
4

Dies gilt nicht, C (da die Namen Foo und Bar nicht auf Typen beziehen, würden Sie das struct Schlüsselwort verwenden oder einen typedef verwenden).

In C++ ist dies eine überraschende, aber gültige Deklaration. Er deklariert b als eine Funktion, die Foo zurückgibt und ein Argument vom Typ "(Zeiger auf) Funktion nimmt, das int zurückgibt, wobei ein Argument vom Typ Zeiger auf Balken genommen wird".

Um eine lesbare Typdeklaration zu erzeugen, habe ich den folgenden Code geschrieben:

#include <typeinfo> 
#include <iostream> 


int main() { 
    struct Foo {}; 
    struct Bar {}; 

    Foo(b)(int (Bar*c)); 
    std::cout << typeid(b).name(); 

    return 0; 
} 

Dann habe ich es kompiliert und gefiltert sein Ausgang durch c++filt. Das Ergebnis war:

main::Foo (int (*)(main::Bar*)) 

, die ganz klar.

+1

Es wäre hilfreich zu erklären, warum es nicht gültig ist C. –

+0

@ JohannesSchaub-litb Hinzugefügt, dass auch. –

2

Eigentlich mein Compiler (Clang 3.5) gibt mir die folgende Warnung:

Warnung: Klammern wurden als Funktion Erklärung vereindeutigt [-Wvexing-Parse]

, die mehr auf ist Punkt, wie Sie es mit Most vexing parse zu tun haben.

Die folgende Erklärung:

Foo(b)(int (Bar*c)); 

deklariert eine bFunktionszeiger auf eine Funktion zeigt, die Foo und nimmt als Argument gibt eine Funktion, die int zurückgibt und Zeiger auf Bar ein Argument (zB: int (Bar*c)).

Ihr Compiler denkt wahrscheinlich, dass dies ein Prototyp einer Funktion ist, also die Warnung.