C ++ Thread, der das Referenzargument verwendet, ist beim Kompilieren fehlgeschlagen

8
%Vor%

Der obige Code schlägt mit der folgenden Fehlermeldung fehl:

%Vor%

Ich verstehe, dass ich std::ref() verwenden kann, um das Argument zu übergeben. Aber wenn ich nach Wert überlasse, warum ist es ein Fehler, da thread das Argument einfach mit value kopieren und ein Objekt innerhalb des Threads übergeben soll, um es mit dem Referenzargument der Funktion f1 .

Ich denke, wenn ich verstehen kann, was dieses result_of macht und warum es Fehler gibt, kann ich den Grund besser verstehen. Könnte also jemand mich durch den Fehler msg führen? Vor allem die Bedeutungen von std::_Bind_simple<void (*(double))(double&)> und std::result_of<void (*(double))(double&)> .

BEARBEITEN : Ich weiß, wenn ich einen Wert übergebe, funktioniert der Thread nur auf der Kopie und hat keine Auswirkungen, nachdem der Thread zurückkehrt. Das ist nicht meine Sache. Ich möchte wissen, warum es jetzt Fehler gibt, aber es gab keinen Fehler zu anderen Posts auf SO wie folgt: Unterschied zwischen Zeiger und Referenz als Thread-Parameter

    
Rich 31.03.2016, 19:10
quelle

2 Antworten

12
  

Ich weiß, wenn ich einen Wert übergebe, wird der Thread nur auf der Kopie funktionieren und hat keine Wirkung, nachdem der Thread zurückkehrt.

Nein, das stimmt nicht. Der Code sollte nicht stillschweigend eine Kopie erstellen und an der Kopie arbeiten, der Standard sagt, es darf nicht einmal kompiliert werden.

Der Standard erfordert, dass die Argumente für die aufgerufene Funktion kopiert werden (in den Speicher, der von der C ++ - Laufzeit verwaltet wird) und dann die Kopien als rvalues ​​ weitergeleitet werden. In Ihrem Beispiel wird f1 an einen R-Wert vom Typ double übergeben und der Parameter vom Typ double& kann nicht an diesen R-Wert gebunden werden.

Der Grund, warum der Standard dies erfordert, ist, dass es kein stilles Kopieren und Verlieren von Daten gibt: Wenn die Funktion eine modifizierbare Referenz benötigt, wird sie nicht kompiliert, es sei denn, Sie übergeben eine Referenz explizit mit reference_wrapper .

Der Compilerfehler, den Sie erhalten, bezieht result_of mit ein, weil ich so GCC std::thread überprüft habe, ob die Funktion mit den angegebenen Argumenten aufgerufen werden kann. Ich verwende result_of<decltype(&f1)(double)> , um zu überprüfen, ob der Funktionszeiger &f1 (der vom Typ void(*)(double&) ist) mit einem Rvalue vom Typ double aufgerufen werden kann. Es kann nicht mit einem Argument dieses Typs aufgerufen werden, daher ist der verschachtelte Typ result_of<decltype(&f1)(double)>::type nicht definiert, daher sagt der Compiler:

%Vor%

Der Fehler ist ein wenig verwirrend, da die C ++ - Deklaratorregeln bedeuten, dass decltype(&f1)(double) als void(*(double))(double&) angezeigt wird.

  

Das geht mich nichts an. Ich will wissen, warum es jetzt Fehler gibt, aber es gab keinen Fehler zu anderen Posts auf SO

Diese Posts verwendeten einen alten vor C ++ 11 oder nicht konformen Compiler, der die Anforderungen des C ++ 11-Standards nicht erfüllte und den Code falsch kompilierte.

    
Jonathan Wakely 31.03.2016, 19:19
quelle
1

Jonathans Antwort ist definitiv. Die Zeit, die damit verbracht wurde, es zu studieren, wäre eine gute Zeit.

In der Zwischenzeit wird das Ändern des Codes so funktionieren, wie Sie wollen - nämlich eine Referenz in die Thread-Funktion senden:

%Vor%     
Richard Hodges 31.03.2016 20:19
quelle

Tags und Links