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 )
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 )
Warum funktioniert das, aber nicht das erste Beispiel?
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).
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<...>'
.