C++中的万能引用和完美转发

本文介绍了C++中的万能引用(Universal Reference)和完美转发(Perfect Forwarding)概念,以及引用折叠(Reference Collapse)规则。通过实例解析了万能引用如何在左值和右值之间切换,并探讨了如何利用完美转发保持变量类型不变,以实现更高效、灵活的模板函数设计。

C++中的万能引用和完美转发

  1. 阅读这篇博文需要了解C++中的左值(lvalue)和右值(rvalue)的概念,详情参见我的另外一篇博文:C++移动语义及拷贝优化
  2. 万能引用和完美转发多涉及到模板的使用,如若不是自己写模板,则可不用关心

万能引用(Universal Reference)

首先,我们来看一个例子:

#include <iostream>

using std::cout;
using std::endl;


template<typename T>
void func(T& param) {
    cout << param << endl;
}


int main() {
    int num = 2019;
    func(num);
    return 0;
}

这样例子的编译输出都没有什么问题,但是如果我们修改成下面的调用方式呢?

int main() {
    func(2019);
    return 0;
}

则会得到一个大大的编译错误。因为上面的模板函数只能接受左值或者左值引用(左值一般是有名字的变量,可以取到地址的),我们当然可以重载一个接受右值的模板函数,如下也可以达到效果。

template<typename T>
C++ 中,可以通过万能引用 `std::forward` 函数实现完美转发万能引用是一种特殊的引用类型,它既能接收左值,也能接收右值,还能接受 `const` 左值 `const` 右值。万能引用会根据传入的实参类型进行推导,若传入左值,那么它就是左值引用类型;若传入右值,那么它就是右值引用类型。其形式通常为 `T&&`,其中 `T` 是模板类型参数。示例如下: ```cpp template <typename T> void PerfectForward(T&& t) { // 这里 t 就是万能引用 } int main() { int x = 1; PerfectForward(x); // 传入左值 PerfectForward(10); // 传入右值 return 0; } ``` `std::forward` 是 C++11 引入的一个标准库函数模板,用于在泛型编程中实现完美转发,它的主要作用是保持传入参数的值类别(左值或右值)不变地传递给另一个函数。结合万能引用 `std::forward` 就能实现完美转发。示例如下: ```cpp #include <iostream> #include <utility> // 接收左值的函数 void func(int& x) { std::cout << "Lvalue reference: " << x << std::endl; } // 接收右值的函数 void func(int&& x) { std::cout << "Rvalue reference: " << x << std::endl; } // 转发函数模板 template<typename T> void wrapper(T&& arg) { func(std::forward<T>(arg)); } int main() { int a = 10; // 传递左值 wrapper(a); // 传递右值 wrapper(20); return 0; } ``` 在上述代码中,`wrapper` 函数模板中的 `T&&` 是万能引用,它可以绑定到左值或右值。在 `wrapper` 函数内部,使用 `std::forward<T>(arg)` 将参数 `arg` 以其原始的值类别转发给 `func` 函数,从而实现了完美转发
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值