何时使用std :: forward来转发参数?

C ++ 0x显示了一个使用std::forward的例子:

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

什么时候使用std::forward是有利的,总是?

另外,它需要在参数声明中使用&& ,在所有情况下都有效吗? 我以为你必须将临时函数传递给一个函数,如果函数是用&&声明的话,那么可以用任何参数调用函数吗?

最后,如果我有这样的函数调用:

 template<int val, typename... Params> void doSomething(Params... args) { doSomethingElse<val, Params...>(args...); } 

我应该用这个来代替:

 template<int val, typename... Params> void doSomething(Params&&... args) { doSomethingElse<val, Params...>(std::forward<Params>(args)...); } 

另外,如果在函数中使用两次参数,即同时转发两个函数,使用std::forward是否明智? 不会std::forward同样的东西临时两次,移动内存,使第二次使用无效? 下面的代码是可以的:

 template<int val, typename... Params> void doSomething(Params&&... args) { doSomethingElse<val, Params...>(std::forward<Params>(args)...); doSomethingWeird<val, Params...>(std::forward<Params>(args)...); } 

我有点困惑了std::forward ,我很乐意使用一些清理。

像你的第一个例子一样使用它:

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

这是因为引用合并规则 :如果T = U& ,那么T&& = U& ,但是如果T = U&& ,那么T&& = U&& ,所以你总是以正确的types在函数体内结束。 最后,如果最初是一个左值,则需要将左值变为x (因为它现在有一个名字!)回到右值引用。

但是,你不能多次转发,因为这是没有意义的。 转发意味着您可能会将参数一直移动到最终的调用者,一旦移动它就消失了,所以您不能再使用它。