何时使用 std::forward 转发参数?
C++0x 展示了一个使用 std::forward
的例子:
C++0x shows an example of using std::forward
:
template<class T>
void foo(T&& arg)
{
bar(std::forward<T>(arg));
}
什么时候总是使用 std::forward
有好处?
When is it advantageous to use std::forward
, always?
另外,它需要在参数声明中使用&&
,是否在所有情况下都有效?我认为如果函数是用 &&
声明的,你必须将临时变量传递给函数,所以可以用任何参数调用 foo 吗?
Also, it requires to use &&
in the parameters declaration, is it valid in all cases? I thought you had to pass temporaries to a function if the function was declared with &&
in it, so can foo be called with any parameter?
最后,如果我有这样的函数调用:
Lastly, if I have a function call such as this:
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
不会将相同的东西两次转换为临时的,移动内存并使其在第二次使用时无效吗?下面的代码可以吗:
Also, if use the parameters twice in the function, i.e. forwarding to two functions at the same time, is it wise to use std::forward
? Won't std::forward
convert the same thing to a temporary twice, moving the memory and make it invalid for a second use? Would the following code be ok:
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
有点困惑,我很乐意使用一些清理方法.
I'm a bit confused by std::forward
, and I'd gladly use some clearing up.
推荐答案
像第一个例子一样使用它:
Use it like your first example:
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&&
,所以你总是在函数体内得到正确的类型.最后,您需要 forward
将左值转换的 x
(因为它现在有了名字!)如果它最初是一个右值引用.
That's because of the reference collapsing rules: If T = U&
, then T&& = U&
, but if T = U&&
, then T&& = U&&
, so you always end up with the correct type inside the function body. Finally, you need forward
to turn the lvalue-turned x
(because it has a name now!) back into an rvalue reference if it was one initially.
但是,您不应该多次转发某些内容,因为这通常没有意义:转发意味着您可能会将参数一直传递到最终调用者,并且一旦它移动它不见了,所以你不能再使用它(按照你可能想要的方式).
You should not forward something more than once however, because that usually does not make sense: Forwarding means that you're potentially moving the argument all the way through to the final caller, and once it's moved it's gone, so you cannot then use it again (in the way you probably meant to).
相关文章