为什么需要转发返回值

Kan*_* Li 8 c++ perfect-forwarding c++11 c++14

在的文档std::forward,给出了以下示例:

template<class T>
void wrapper(T&& arg)
{
    foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get()));
}
Run Code Online (Sandbox Code Playgroud)

为什么在这里需要转发返回值?在什么情况下它与以下代码不同:

template<class T>
void wrapper(T&& arg)
{
    foo(forward<T>(arg).get());
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*las 5

让我们分解可能性。T::get可以返回左值引用(是左值表达式),右值引用(是xvalue表达式)或prvalue。

forward表达式会将左值表达式转换为...左值表达式。它将xvalue转换为xvalue。并将prvalue转换为xvalue。

对于prvalue和xvalue表达式,关于重载解析中参数如何绑定到参数的C ++规则是相同的。因此,最后两个总是调用相同的函数。

因此,外部forward无能为力。确实,这比什么都不做更糟。为什么?

因为C ++ 17及更高版本中的prvalue可以保证省略。xvalues 。如果foo按值接受参数,则附加参数forward将显示不必要的临时变量,然后将其移至参数中。如果类型比复杂int,则很有可能会失去一些性能。

因此,请勿转发将直接作为函数参数传递的返回值。如果需要将值存储在中间auto&&变量中,则需要转发该值。但是,如果您要像这样原位进行操作,那就不要。