OOP-THU icon indicating copy to clipboard operation
OOP-THU copied to clipboard

std::forward介绍(补充参数转发知识)

Open ulyanacreates opened this issue 2 years ago • 2 comments

课上讲过实现左值与右值转发的一个工具——std::move,我这边想介绍一下实现完美转发的工具,std::forward。

Note: 所谓“完美转发”是指把参数“原封不动”传给函数。若参数是右值,则参数转为右值;若参数是左值,则传为左值。这样保证了不会丢失参数原本性质。这个方法面向与解决不必要的拷贝函数调用,同时也提高了程序效率。

std::forward 则解决了完美转发提出的问题。与std::move相比,它的目的是保持参数原本形式,不能从左值换成右值。它在的声明如下:

  1. template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept;
  2. template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;_ 这样std::forward根据接收参数的实际类型来判断传右值或者左值。何况,返回类型是引用,因此保证了转发中不能复制参数。

使用例子如下:

#include <utility> 
#include <iostream> 
void checkVal(const int& x) {  //左值转移
    std::cout << "[lvalue]";
} 
void checkVal(int&& x) {  //右值转移
    std::cout << "[rvalue]";
} 
template <class T> 
void func (T&& x) {// 无论传给右值还是左值,都对函数里面构造临时对象x,x 总是 左值
     checkVal(x); 
     checkVal(std::forward<T>(x)); //根据参数实际情况转移左值或右值
} 
int main () { 
     int a;
     std::cout << "calling func with lvalue: ";
     fn (a);
     std::cout << std::endl;
     std::cout << "calling func with rvalue: ";
     fn (0);
     std::cout << std::endl; 
    return 0; 
}

输出: calling func with lvalue: [lvalue][lvalue] calling func with rvalue: [lvalue][rvalue]

因此,std::forward 实现了完美转发原理,在传参数中保留了参数原本性质,也避免了传右值时调用拷贝函数,从此提高了程序的效率。

ulyanacreates avatar Jun 16 '22 10:06 ulyanacreates

std::forward重点 stdForward.pptx

ulyanacreates avatar Jun 16 '22 10:06 ulyanacreates

OK

Yu-Shi avatar Jul 04 '22 14:07 Yu-Shi