std :: async unter Verwendung einer an ein Lambda gebundenen rvalue-Referenz

8

Ich versuche, eine rvalue-Referenz mit std::bind an ein Lambda zu binden, aber ich habe Probleme, wenn ich das in einen std::async -Aufruf werfe: ( Quelle )

%Vor%

Dies führt zu einem Compiler-Fehler. Ich bin mir nicht sicher, wie ich das interpretieren soll:

  

Fehler: kein Typ namens "type" in "class std :: result_of (std :: basic_string) & gt; & amp; () & gt; '

Was ist hier los? Interessanterweise kompiliert und funktioniert eine leichte Modifikation wie erwartet. Wenn ich std::string{"hello world"} in ein C-String-Literal ändere, funktioniert alles: ( Quelle )

%Vor%

Warum funktioniert das, aber nicht das erste Beispiel?

    
huu 06.05.2015, 18:04
quelle

1 Antwort

11

std::bind wird eine Kopie des std::string -Arguments erstellen und diese an das Lambda übergeben. Aber das kann nicht kompiliert werden, weil das Lambda ein rvalue-Argument benötigt, während das, was bind passiert, ein lvalue ist. Du könntest das zum Laufen bringen, wenn du bind to move das Argument bekommst, aber das erfordert extrem hässliches Casting zur Disambiguierung (weil std::move ist eine überladene Funktion).

%Vor%

Live-Demo

Sie könnten natürlich Ihre eigene Version von move schreiben, die nicht überladen ist, und diese Umwandlung vermeiden.

Der zweite Fall funktioniert, weil, wenn bind die char const * an das Lambda übergibt, implizit ein rvalue std::string temporary erzeugt wird.

Um die angezeigte Fehlermeldung zu erklären, wird% std::async irgendwo im Inneren von std::result_of aufgerufen, um den Rückgabetyp des Funktionsaufruf-Ausdrucks zu bestimmen. Da dieser Aufrufausdruck jedoch aus den oben genannten Gründen ungültig ist, wird result_of SFINAE ". d out (das ist eine C ++ 14 Änderung). Daher der Fehler error: no type named 'type' in 'class std::result_of<...>' .

    
Praetorian 06.05.2015, 18:22
quelle

Tags und Links