为什么需要转发返回值
Why forwarding return value is needed
在std::forward
的文档中,它给出了以下示例:
template<class T>
void wrapper(T&& arg)
{
foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get()));
}
为什么这里需要转发返回值?它与以下代码不同的情况是什么:
template<class T>
void wrapper(T&& arg)
{
foo(forward<T>(arg).get());
}
让我们分解一下可能性。T::get
可以返回左值引用(即左值表达式)、右值引用(即 xValue 表达式)或 prvalue。
forward
表达式会将左值表达式转换为...左值表达式。它会将 xvalue 转换为...一个 x值。它会将 prvalue 转换为 xvalue。
C++关于参数如何绑定到重载解析中的参数的规则对于 prvalue 和 xvalue 表达式是相同的。因此,最后两个将始终调用相同的函数。
因此,外在的forward
什么也做不了。事实上,这比什么都不做更糟糕。为什么?
因为 C++17 及以上的 prvalues 可以保证省略;xvalues则不能。如果foo
按值获取参数,则附加forward
将显示不必要的临时参数,然后将其移动到参数中。如果类型比int
更复杂,那么您很有可能会失去一些性能。
因此,不要转发将要直接作为函数参数传递的返回值。如果需要将值存储在中间auto&&
变量中,则需要转发该值。但是,如果您像这样在原地进行,请不要这样做。
添加它的编辑声称它是第二个重载的示例:
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type&& t ) noexcept;
这个例子不是很好,因为已经是一个右值。实际上,我认为第二个重载并没有那么有用,除了使:
std::forward<decltype(expression)>(expression);
适用于所有表达式(包括如果expression
是右值),但std::forward
的大多数用例仅限于T&&
和auto&&
的左值。
相关文章:
- 从python中调用C++函数并获取返回值
- 为什么模板类中的对象不能返回值
- 返回值优化:显式移动还是隐式
- lock_guard是否保护返回值
- 调用CreateProcess()并获取字符串的返回值
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 查找 GCD:并非所有控制路径都返回值
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 如何从 std::thread 返回值
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- 方法错误"not all control paths return a value"和方法不返回值
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 对fread的返回值感到困惑
- 程序不向函数返回值
- 返回值的完美转发?
- 为什么需要转发返回值
- 使用auto&&完美转发返回值
- 转发通用可可对象的返回值