Wann sollte std :: forward verwendet werden, um Argumente weiterzuleiten?

C ++ 0x zeigt ein Beispiel für die Verwendung von std::forward :

 template void foo(T&& arg) { bar(std::forward(arg)); } 

Wann ist es vorteilhaft, std::forward immer zu verwenden?

Außerdem muss && in der Parameter-Deklaration verwendet werden, ist es in allen Fällen gültig? Ich dachte, du hättest Provisorien an eine function übergeben müssen, wenn die function mit && darin deklariert wurde, also mit irgendeinem Parameter aufgerufen werden kann?

Zuletzt, wenn ich einen functionsaufruf wie diesen habe:

 template void doSomething(Params... args) { doSomethingElse(args...); } 

Soll ich das stattdessen verwenden:

 template void doSomething(Params&&... args) { doSomethingElse(std::forward(args)...); } 

Wenn Sie die Parameter zweimal in der function verwenden, also gleichzeitig an zwei functionen weiterleiten, ist es ratsam, std::forward . Wird nicht std::forward das Gleiche zweimal in ein temporäres konvertieren, den Speicher verschieben und für eine zweite Verwendung ungültig machen? Wäre der folgende Code in Ordnung:

 template void doSomething(Params&&... args) { doSomethingElse(std::forward(args)...); doSomethingWeird(std::forward(args)...); } 

Ich bin etwas verwirrt von std::forward , und ich würde gerne etwas aufräumen.

Verwenden Sie es wie Ihr erstes Beispiel:

 template  void f(T && x) { g(std::forward(x)); } template  void f(Args && ...args) { g(std::forward(args)...); } 

Das liegt an den kollabierenden Referenzregeln : Wenn T = U& , dann ist T&& = U& , aber wenn T = U&& , dann gilt T&& = U&& , so dass Sie immer den richtigen Typ innerhalb des functionskörpers haben. Schließlich brauchen Sie forward , um das lval-gedrehte x (weil es jetzt einen Namen hat!) Zurück in eine rvalue-Referenz zu drehen, wenn es ursprünglich eine war.

Sie sollten jedoch nicht mehr als einmal etwas weiterleiten, weil das normalerweise keinen Sinn ergibt: Weiterleiten bedeutet, dass Sie das Argument möglicherweise bis zum letzten Aufrufer verschieben, und wenn es einmal verschoben wurde, ist es weg, sodass Sie es nicht mehr verwenden können wieder (in der Art und Weise, wie du es wahrscheinlich wolltest).