【C++】万能引用、完美转发

简介: 【C++】万能引用、完美转发

万能引用

万能引用的格式如下:

template<typename T>
void PerfectForward(T&& t)
{
  Fun(t);
}

虽然写的是&&和右值引用类似,但是它可以接收左值引用和右值引用

当传过来的是左值,那么T&&会折叠为T&

引用折叠有以下几种情况:

实参 形参 结果
&(左值) &(左值) &(左值)
&(左值) &&(右值) &(左值)
&&(右值) &&(右值) &&(右值)
&&(右值) &(左值) &(左值)

举个栗子😉

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }
template<typename T>
void PerfectForward(T&& t)
{
  Fun(t);
}
int main()
{
  PerfectForward(10);           // 右值
  int a;
  PerfectForward(a);            // 左值
  PerfectForward(std::move(a)); // 右值
  const int b = 8;
  PerfectForward(b);          // const 左值
  PerfectForward(std::move(b)); // const 右值
  cout << "----------------------------------" << endl;
  return 0;
}

这里输出为什么都是左值引用呢?

chatgpt的回答:

这是因为在 C++ 中,当一个命名的变量被作为参数传递给函数时,它会被视为左值,即使该变量是通过 std::move 显式转换为右值引用的。

我的理解:

因为无论是什么类型作为函数参数接收,就有了载体,就会存在一片空间去存储值了,因此原来的右值有了空间只会就有了地址,就会被认为是左值。

这种情况也被称为不完美转发。

完美转发

经过引用折叠之后,传之前的数据的引用类型和传入之后的引用类型可能发生变化,为了保证类型不会发生变化,完美转发就产生了。

std::forward<>();

对于之前的代码,加上万能转发就能够正确输出类型了。

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }
template<typename T>
void PerfectForward(T&& t)
{
  Fun(std::forward<T>(t));
}
int main()
{
  PerfectForward(10);           // 右值
  int a;
  PerfectForward(a);            // 左值
  PerfectForward(std::move(a)); // 右值
  const int b = 8;
  PerfectForward(b);          // const 左值
  PerfectForward(std::move(b)); // const 右值
  cout << "----------------------------------" << endl;
  return 0;
}

注意:只要使用了完美转发,每一步调用涉及到参数的都必须加上万能转发,不然就会失败。

目录
相关文章
|
8月前
|
存储 编译器
【c++11】万能引用和完美转发
【c++11】万能引用和完美转发
|
2天前
|
前端开发 JavaScript
怎样使用接口引用数据
怎样使用接口引用数据
|
2天前
|
安全
代理ip的优势、用途及注意事项
代理ip的优势、用途及注意事项
|
2天前
|
C++ 容器
【C++11特性篇】一文带小白轻松理解【万能引用(引用折叠)】&【完美转发】
【C++11特性篇】一文带小白轻松理解【万能引用(引用折叠)】&【完美转发】
|
6月前
|
网络架构
探秘公有IP地址与私有IP地址的区别及其在路由控制中的作用
本文将深入探讨公有IP地址和私有IP地址的区别和作用,并介绍了在路由控制中如何使用IP地址来确定下一跳路由器。了解这些概念和技术将有助于读者更好地理解互联网通信的原理和过程。
105 1
探秘公有IP地址与私有IP地址的区别及其在路由控制中的作用
|
8月前
|
C++
C++中的万能引用和完美转发
C++中的万能引用和完美转发是什么呢?有什么用?
39 1
|
9月前
|
存储 编译器 C++
【C++11】右值引用和移动语义 万能引用和完美转发(一)
【C++11】右值引用和移动语义 万能引用和完美转发(一)
58 0
|
9月前
|
编译器 C++ 容器
【C++11】右值引用和移动语义 万能引用和完美转发(二)
【C++11】右值引用和移动语义 万能引用和完美转发(二)
70 0
|
安全
非法文件的包含攻击是什么意思?底层原理是什么?
非法文件的包含攻击是什么意思?底层原理是什么?
213 0
|
前端开发
前端学习案例4-this指向问题-隐式调用规则2
前端学习案例4-this指向问题-隐式调用规则2
59 0
前端学习案例4-this指向问题-隐式调用规则2