2016-06-15 10 views
6

Heute war ich mit folgenden falschem Code Stück helfen (func wurde mit int param erklärt, aber int* wurde als zweiter param an std::thread Konstruktor übergeben):Wie interpretiere ich diesen C++ Typ?

#include <thread> 

void func(int); 
int* ptr; 

void start() 
{ 
    std::thread t = std::thread(func, ptr); 
} 

Als ich versuchte, diese 5.3.0 mit gcc zu kompilieren, es gedruckt Fehlermeldung mit folgenden Art:

class std::result_of<void (*(int*))(int)> 

Jetzt frage ich mich, wie Typ als Parameter übergeben class std::result_of<> zu interpretieren. Es ist ähnlich wie Zeiger auf Funktion (in diesem Fall void(*)(int)), aber mit extra (int*) nach Stern in Klammern. Wie interpretiere ich diesen Typ?

+0

Wenn 'func' ein' int' erfordert, warum passierst du ein 'int *'? – NathanOliver

+0

Das war ein Fehler im Code, den ich heute sah - wahrscheinlich war das ein Tippfehler. –

+2

Eine ähnliche Aussage gibt [dies nach cdecl] (http://cdecl.ridiculousfish.com/?q=void+%28*f%28int*%29%29%28int%29). – ArchbishopOfBanterbury

Antwort

5
void (*(int*))(int) 

Is:

eine Funktion, die einen einzigen Parameter des Typs int* als kehrt

ein Zeiger auf eine Funktion, die einen einzigen Parameter des Typs int und gibt

void

nimmt nimmt

Es ist ähnlich dem C/C++ Standard-Bibliotheksfunktion signal:

void (*signal(int sig, void (*func)(int)))(int); 

die einen Zeiger zu einem vorhergehenden Signalbehandlungsroutine zurückkehrt (die aus dem gleichen Typ wie der func Parameter ist).

EDIT: Wie Pete Becker pointed out in comment, wenn sie mit std::result_of verwendet, es means something different, aber Art des Ausdrucks selbst noch der Typ I beschrieben, std::result_of interpretiert es einfach anders.

+0

Danke, ich sehe es jetzt. Ich fing an, von falschem Punkt zu entschlüsseln und wurde verwirrt. –

+1

Ja, so würde es in der realen Welt sein. Aber das ist ** nicht **, was es bedeutet, wenn es der Argumenttyp für 'std :: result_of' ist, der diese Notation entführt, um einen aufrufbaren Typ und seine Argumentliste darzustellen. –

+0

@PeteBecker Ich dachte, dass OP über diese Erklärung verwirrt war. Ich habe noch nie von 'std :: result_of' gehört (weil ich C++ gelernt habe, nachdem C++ 11 herauskam, also benutze ich nur' decltype' und neue Funktionen), danke für deine Erklärung. Ich werde meine Antwort bearbeiten. – PcAF

7

Dies ist nicht so einfach wie es aussieht. std::result_of missbraucht das Typsystem, um Informationen über einen Funktionsaufruf einzufügen, damit es herausfinden kann, wie der Rückgabetyp des Funktionsaufrufs aussehen würde.

Das Argument std::result_of hat die Form Fty(T1, T2, ...), wo Fty ein aufrufbare Typ ist und T1 usw. sind die Typen der Argumente, die es mit genannt wird. Angesichts dieser Informationen hat std::result_of einen verschachtelten Typ mit dem Namen type, der ein Synonym für den Rückgabetyp des Aufrufs eines aufrufbaren Typs mit der Signatur Fty mit Argumenten der angegebenen Typen ist. Puh, das ist ein Bissen.

Also, in result_of<void (*(int*))(int)> gibt es zwei Teile der Vorlage Argument. Der erste Teil ist void (*(int*)), welcher der aufrufbare Typ ist. In diesem Fall ist es ein Zeiger zur Funktion, der int* nimmt und void zurückgibt. Der zweite Teil ist (int), was die Typenliste für die vorgeschlagenen Argumente ist.

Also was das sagen soll ist, dass std::result_of instanziiert wird mit einer Funktion, deren Typ ist void (*(int*)) und mit einer Argumentliste von (int). Und das ist das Problem, wie Sie angegeben haben: Sie können ein Argument vom Typ int nicht an eine Funktion übergeben, die ein Argument vom Typ int* verwendet.

Sind Sie nicht froh, dass Sie gefragt haben? (Übrigens, das ist ziemlich low-level Vorlage Hacker, die nicht mehr benötigt wird; decltype ist eine viel sauberere Möglichkeit, den Rückgabetyp eines Funktionsaufrufs herauszufinden).

+0

Ja, das war am Anfang verwirrend. Danke für die Erklärung. –

Verwandte Themen