RValue Refs, std::move, best practice
-
Nathan schrieb:
*Ideone überrascht mich da aber: http://ideone.com/GtERzZ
Kann es sein, dass der Compiler das Temporary direkt im Argument erstellt?Wenn ich das richtig gelesen habe, ist es in der Tat so, dass Compiler nicht benötigte Kopien/Moves in Argumente komplett weg optimieren können, ähnlich wie beim Rückgabewert.
Nathan schrieb:
Wenn ja, ist diese Variante genauso gut, wie die mit T&&.
Fast, denn das weg optimieren geht wohl nur bei echten Temporaries und nicht bei std::move.
-
Kellerautomats Code mit richtigen Bezeichnern:
template <typename... T> void emplace(T&&... msg) { std::lock_guard<std::mutex> lock(mtx); queue.emplace_front(std::forward<T>(msg)...); cond.notify_one(); } void post(T const& msg) { emplace(msg); } void post(T&& msg) { emplace(std::move(msg)); }
-
Nathan schrieb:
Ich hab mal eine Klasse gesehen, die das Argument entweder als LValue oder RValue Referenz speichert, jenachdem was es ist. Das ermöglicht dann effiziente Übergabe an die entsprechenden Copy/Movectors.
Hier sowas in der Art meinte ich: http://ideone.com/fTORB3
Es kommen zwar zustätzliche Kosten (if Abfrage und ein weitere Def-Ctor), aber das ist in der Regel billig. Und man hat somit das beste von beiden Seiten: genau die Aufrufe, die man haben will, und wenig Tipparbeit.
-
Nathan schrieb:
Hier sowas in der Art meinte ich: http://ideone.com/fTORB3
Es kommen zwar zustätzliche Kosten (if Abfrage und ein weitere Def-Ctor), aber das ist in der Regel billig. Und man hat somit das beste von beiden Seiten: genau die Aufrufe, die man haben will, und wenig Tipparbeit.

-
Hier noch eine verbesserte Version, die auch mit Konvertierungen klar kommt und keinen zustätzlichen Overhead (abgesehen vom if-else und dem Erzeugen das fast_arg) bietet: http://ideone.com/uIIPMi
-
emplac0r schrieb:
Kellerautomats Code mit richtigen Bezeichnern:
template <typename... T> void emplace(T&&... msg) { std::lock_guard<std::mutex> lock(mtx); queue.emplace_front(std::forward<T>(msg)...); cond.notify_one(); } void post(T const& msg) { emplace(msg); } void post(T&& msg) { emplace(std::move(msg)); }
-
Warum nicht einfach so?
template <typename U> void post(U &&msg) { std::lock_guard<std::mutex> lock(mtx); queue.push_front(std::forward<U>(msg)); cond.notify_one(); }
-
TyRoXx schrieb:
Warum nicht einfach so?
Um es sich nicht mit Stroustrup zu verscherzen.
Stroustrup schrieb:
Improved push operations: My favorite container operation is push_back() that allows a container to grow gracefully:
vector<pair<string,int>> vp; string s; int i; while(cin>>s>>i) vp.push_back({s,i}); // {s,i} geht nur, wenn kein Template
-
Danke fuer eure Vorschlaege, std::forward werde ich wohl etwas naeher beleuchten. Aber eine Hilfsklasse wird es nicht geben. Tipparbeit ist fuer mich nie ein Grund.
-
knivil schrieb:
Danke fuer eure Vorschlaege, std::forward werde ich wohl etwas naeher beleuchten. Aber eine Hilfsklasse wird es nicht geben. Tipparbeit ist fuer mich nie ein Grund.
Es geht nicht nur um Tipparbeit, sondern auch um Übersichtlichkeit und Wartbarkeit. Bei doppeltem Code kann man zwei Fehler korrigieren müssen oder in einer Implementierung einen Fehler haben, den man schwer findet.