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)
让我们分解可能性。T::get
可以返回左值引用(是左值表达式),右值引用(是xvalue表达式)或prvalue。
该forward
表达式会将左值表达式转换为...左值表达式。它将xvalue转换为xvalue。并将prvalue转换为xvalue。
对于prvalue和xvalue表达式,关于重载解析中参数如何绑定到参数的C ++规则是相同的。因此,最后两个总是调用相同的函数。
因此,外部forward
无能为力。确实,这比什么都不做更糟。为什么?
因为C ++ 17及更高版本中的prvalue可以保证省略。xvalues 不。如果foo
按值接受参数,则附加参数forward
将显示不必要的临时变量,然后将其移至参数中。如果类型比复杂int
,则很有可能会失去一些性能。
因此,请勿转发将直接作为函数参数传递的返回值。如果需要将值存储在中间auto&&
变量中,则需要转发该值。但是,如果您要像这样原位进行操作,那就不要。