【c++11】万能引用和完美转发

简介: 【c++11】万能引用和完美转发

这一节是对上一篇右值引用的补充。

链接: 右值引用

万能引用

看如下代码

void Fun(int &x){ cout << "左值引用" << endl; }
void Fun(const int &x){ cout << "const 左值引用" << endl; }
void Fun(int &&x){ cout << "右值引用" << endl; }

fun()函数进行了重构,当我们调用函数时,编译器会根据我们的实参来判断调用最匹配的函数,这是的大家都知道的事情。

但是,

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

当传右值时,正常调用

当传递左值时,&& 会进行折叠,所以也叫折叠引用

看接下来的代码:

template<class T>
void func1(T&& z)
{
  fun(z);
}
int main()
{
  int a=10;
    func1(10);      //右值
  func1(a);       //右值
    return 0;
}

同时传左值和右值,也可以正常运行,当然

void func1(const  int& z){}

也可以成功调用上述代码,但是该方法无法保存实参的右值属性,在传递过程中就改变了参数的属性。

运行结果:

当调用了fun()函数后,怎么显示的都是左值引用怎么回事呢?


要注意的是右值是不能取地址的,但是给右值取别名后,会导致右值被存储到特定位置,且可以取到该位置的地址,也就是说例如:不能取字面量10的地址,但是ref引用后,可以对rr1取地址,也可以修改rr1。如果不想rr1被修改,可以用const int&& rr1 去引用,是不是感觉很神奇。

10    //纯右值
int&& ref=10;  //  ref是一个左值

所以当右值传递给z后,z已经是一个左值了,所以最后的结果是打印出两次的左值引用。

那么如何解决呢?

就需要学习接下来的完美转发。

完美转发

std::forward 完美转发在传参的过程中保留对象原生类型属性。

template<class T>
void func1(T&& z)
{
  fun(forward<T>(z));
}
int main()
{
  int a=10;
    func1(10);      //右值
  func1(a);       //右值
    return 0;
}

再次运行:

可以看出,一个右值引用一个左值引用,保持对象原生属性类型。

这对右值引用做了很好的一个补充,我们在实习一些比较复杂的项目中,在某一个函数复用函数是很常见的行为,经常叠加了好几层复用,如果传递右值,就需要完美转发来保存其原生属性。

注意:对每一层的调用都需要进行一次完美转发:forward(),否则参数的原生属性还是会改变。

相关文章
|
2月前
|
存储 安全 C++
C++中的引用和指针:区别与应用
引用和指针在C++中都有其独特的优势和应用场景。引用更适合简洁、安全的代码,而指针提供了更大的灵活性和动态内存管理的能力。在实际编程中,根据需求选择适当的类型,能够编写出高效、可维护的代码。理解并正确使用这两种类型,是掌握C++编程的关键一步。
44 1
|
3月前
|
C++
C++中的const指针与const引用
C++中的const指针与const引用
45 2
|
21天前
|
存储 安全 C++
浅析C++的指针与引用
虽然指针和引用在C++中都用于间接数据访问,但它们各自拥有独特的特性和应用场景。选择使用指针还是引用,主要取决于程序的具体需求,如是否需要动态内存管理,是否希望变量可以重新指向其他对象等。理解这二者的区别,将有助于开发高效、安全的C++程序。
16 3
|
1月前
|
存储 自然语言处理 编译器
【C++入门 三】学习C++缺省参数 | 函数重载 | 引用
【C++入门 三】学习C++缺省参数 | 函数重载 | 引用
|
2月前
|
存储 安全 编译器
【C++航海王:追寻罗杰的编程之路】引用、内联、auto关键字、基于范围的for、指针空值nullptr
【C++航海王:追寻罗杰的编程之路】引用、内联、auto关键字、基于范围的for、指针空值nullptr
47 5
|
2月前
|
C++
C++引用
C++引用
13 1
|
2月前
|
存储 安全 编译器
【C++入门】—— C++入门 (中)_引用
【C++入门】—— C++入门 (中)_引用
27 5
|
2月前
|
C语言 C++ 编译器
【C++语言】冲突-C语言:输入输出、缺省参数、引用、内联函数
【C++语言】冲突-C语言:输入输出、缺省参数、引用、内联函数
【C++语言】冲突-C语言:输入输出、缺省参数、引用、内联函数
|
1月前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。