在readyMasks
的{{3}}中,给出了以下示例:
std::forward
为什么这里需要转发返回值?在什么情况下它与以下代码不同:
template<class T>
void wrapper(T&& arg)
{
foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get()));
}
答案 0 :(得分:5)
让我们打破可能性。 T::get
可以返回左值引用(是左值表达式),右值引用(是xvalue表达式)或prvalue。
forward
表达式会将左值表达式转换为...左值表达式。它将xvalue转换为... xvalue。并将prvalue转换为xvalue。
关于重载解析中的参数如何绑定到参数的C ++规则相同。因此,最后两个总是调用相同的函数。
因此,外部forward
无法完成任何操作。确实,更糟糕比什么都不做。为什么?
因为C ++ 17和更高版本中的prvalue保证了省略; xvalues 不。如果foo
按值接受参数,则附加的forward
将显示不必要的临时变量,然后将其移至参数中。如果类型比int
更复杂,则很有可能会失去一些性能。
因此,请勿转发将直接作为函数参数传递的返回值。如果需要将值存储在中间变量auto&&
中,则需要转发该值。但是,如果您要像这样原位进行操作,那就不要。
答案 1 :(得分:3)
The edit it was added in声称这是第二次重载的一个示例:
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type&& t ) noexcept;
示例不是很好,因为已经是右值。实际上,我认为第二个重载没有什么用,除了使:
std::forward<decltype(expression)>(expression);
适用于所有表达式(包括expression
是右值),但是std::forward
的大多数用例仅限于T&&
和auto&&
的左值。