Cuándo usar std :: forward para reenviar argumentos?

C ++ 0x muestra un ejemplo de uso de std::forward :

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

¿Cuándo es ventajoso usar std::forward , always?

Además, requiere usar && en la statement de parámetros, ¿es válido en todos los casos? Pensé que tenías que pasar temporarios a una función si la función se declaró con && en ella, entonces ¿se puede llamar con algún parámetro?

Por último, si tengo una llamada de función como esta:

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

Debo usar esto en su lugar:

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

Además, si usa los parámetros dos veces en la función, es decir, reenvía a dos funciones al mismo tiempo, ¿es aconsejable usar std::forward ? No std::forward convierte lo mismo en temporal dos veces, ¿mueve la memoria y la invalida para un segundo uso? ¿El siguiente código estaría bien?

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

Estoy un poco confundido por std::forward , y con gusto usaré un poco de aclaración.

Úselo como su primer ejemplo:

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

Esto se debe a las reglas de colapso de referencia : si T = U& , entonces T&& = U& , pero si T = U&& , entonces T&& = U&& , por lo que siempre termina con el tipo correcto dentro del cuerpo de la función. Finalmente, necesita forward el x convertido por valor (porque ahora tiene un nombre) a una referencia rvalue si fue uno inicialmente.

Sin embargo, no debes reenviar algo más de una vez, porque eso normalmente no tiene sentido: reenviar significa que estás moviendo potencialmente el argumento hasta la última persona que llama, y ​​una vez que se mueve ya no está, entonces no puedes usarlo de nuevo (en la forma en que probablemente quisiste hacerlo).