美文网首页
完美转发

完美转发

作者: 疾风2018 | 来源:发表于2022-02-25 16:05 被阅读0次

解决的问题

当一个函数接收右值参数后,再将此参数传给另外一个函数时本是右值的参数变成左值,造成无法利用针对右值的性能优化的问题。

解决方法

在模板中用std::forward<T>(x)来实现“完美转发”,即原来的左值参数仍为左值,原来的右值参数保持为右值。

实现方法

根据模板中引用折叠的规则:

T& & –> T&
T&& & –> T&
T& && –>T&
T&& && –> T&&

std::forward() 用static_cast<T&&> 来实现完美转发。

_NODISCARD constexpr _Ty&& forward(
    remove_reference_t<_Ty>& _Arg) noexcept { // forward an lvalue as either an lvalue or an rvalue
    return static_cast<_Ty&&>(_Arg);
}

虽然不能隐式的将一个左值转换为右值引用,但是可以通过static_cast显示地将一个左值转换为一个右值。

如何理解 std::forward

程序告诉编译器,这个非引用变量我不再用了,可以作为右值传给调用堆栈的下一级,编译器可以依赖此声明放心去做优化(比如调用移动构造器而非拷贝构造器)了。

一般用于将传入的参数转发给下一级函数,自己实际上不会做任何处理,因此叫“完美转发”。传进来的参数可能有三种情况:

  1. 值传递 Type arg
  2. 引用传递 const Type & arg
  3. 右值引用传递 Type && arg

右值引用传递进来的参数由于已经有了参数名字,再传给下一级被调用函数时就会被当成左值。因为这个参数在调用函数后仍然可以继续使用,而右值的特点是该右值一旦传递给子函数之后,就不会在本函数内再次使用。

而std::forward告诉编译器,我的这个参数,在转发给子函数(或者是成员变量的构造函数)后,不再使用。这样才能被当成右值传递过去。

但是如果接收的参数是引用,那么代表着外界可能会有地方仍然用到这个被引用的变量,所以不能说“我不用了”就代表这个值可以当右值,因为不能保证外界有没有在用,所以引用类型的参数,在forward时仍然是被当成左值使用。

传右值的含义是“本调用方函数放弃对该变量的内容的所有权,未来不会再用该变量”。

相关文章

  • 完美转发

    解决的问题 当一个函数接收右值参数后,再将此参数传给另外一个函数时本是右值的参数变成左值,造成无法利用针对右值的性...

  • 完美转发

    万能引用 模板中的&&不代表右值引用,而是万能引用,其既能接收左值又能接收右值。 模板的万能引用只是提供了能够接收...

  • iOS消息转发、完美转发

    http://blog.ibireme.com/2013/11/26/objective-c-messaging/...

  • 06 移动语义与 enable_if

    完美转发(Perfect Forwarding) 要用一个函数将实参的如下基本属性转发给另一个函数可修改的对象转发...

  • 引用折叠和完美转发

    原文:https://zhuanlan.zhihu.com/p/50816420[https://zhuanlan...

  • 【C++ Templates(6)】移动语义与enable_if

    完美转发 假设想写出转发传递实参的如下基本属性的泛型代码可修改的对象转发后应该仍可以被修改常量对象应该作为只读对象...

  • 这个世界有诸多不完美的地方

    这个世界有诸多不完美的地方但是你还得爱他。 我从来不喜欢转发什么QQ群消息,觉得那种转发没意义,甚至幼稚。 然而,...

  • 【转发】没有‘’太极‘’的生活不是完美的生活…

    【转发】没有‘’太极‘’的生活不是完美的生活… 练太极拳了!!! 生活中融入太极,让我...

  • 关于C++ 0x的右值引用

    右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践角度讲,它能够完美解决...

  • C++11新特性--完美转发

    转发的问题     在模板编程中,常有一种场景是把模板参数转发给另一个函数调用,这时候如果只提供值传递版本会显得效...

网友评论

      本文标题:完美转发

      本文链接:https://www.haomeiwen.com/subject/dlexrrtx.html