2016-05-15 10 views
2

Offensichtlich ist es möglich, einen rvalue Verweis auf std::thread Konstruktor zu übergeben. Mein Problem ist mit der Definition dieses Konstruktors in cppreference. Er sagt, dass dieser Konstruktor:wie std :: thread-Konstruktor rvalue-Referenz erkennt?

template< class Function, class... Args > 
explicit thread(Function&& f, Args&&... args); 

Erstellt neues std :: Thread-Objekt und verbindet sie mit einem Faden von Ausführung. Zunächst werden die Konstruktor Kopien/verschiebt alle Argumente (sowohl die Funktionsobjekt f und alle args ...) einzufädeln zugänglichen Speicher als ob durch die Funktion:

template <class T> 
typename decay<T>::type decay_copy(T&& v) { 
    return std::forward<T>(v); 
} 

Soweit ich überprüfen kann:

std::is_same<int, std::decay<int&&>::type>::value 

gibt wahr zurück. Dies bedeutet, std::decay<T>::type wird Rvalue Referenzteil des Arguments fallen lassen. Dann, wie std::thread Konstruktor weiß, welches Argument von Lvalue oder Rvalue Referenzen übergeben wird? Da alle T& und T&& wird T von std::decay<T>::type

+0

"Wendet lvalue-to-rvalue, array-to-pointer und implizite function-to-pointer-Konvertierungen auf den Typ T an, entfernt cv-qualifiers und definiert den resultierenden Typ als Member typedef-Typ" http: // de.cppreference.com/w/cpp/types/decay - wo siehst du, dass Referenzen fallen? – xaxxon

+0

@xaxxon fehlt Ihnen ':: type'. –

+0

@ T.C. entfernt - aber warum sind sie gleich? – xaxxon

Antwort

2
auto s = std::decay_copy(std::string("hello")); 

umgewandelt werden äquivalent zu:

template<> 
std::string std::decay_copy<std::string>(std::string&& src) { 
    return std::string(std::move(src)); 
} 

std::string s = decay_copy<std::string>(std::string("hello")); 
+0

ist das C++? .... Ich habe noch nie einen Funktionsnamen gesehen, der mit <> darin – xaxxon

+0

@xaxxon mehr oder weniger deklariert ist. Es versucht, das Ergebnis der Template-Erweiterung zu demonstrieren. –

1

Es häufiges Problem der perfekten Weiterleitung ist. Wenn Sie Informationen über rvalue in der Funktion wiederherstellen möchten, müssen Sie std :: forward std::forward verwenden. Wenn Sie an der Wertetyp-Erkennung interessiert sind, können Sie dies value_category lesen. In der Beschreibung finden Sie Informationen darüber, wie der Compiler rvalue, xvalue, lvalue, prvalue, gvalue zur Kompilierzeit erkennt.

3

Der std::thread Konstruktor kennt den Wert der Kategorie ihrer Argumente, weil sie weiß, was Function und Args... sind, die es verwendet, um perfekt uns darauf, die seine Parameter zu decay_copy (oder gleichwertig).

Die eigentliche Thread-Funktion kennt den Werttyp nicht. Es wird immer als rvalue mit allen rvalue-Argumenten aufgerufen - was einen Sinn ergibt: Die Kopien von f und args... sind lokal für den Thread und werden nirgendwo sonst verwendet.