首页 > 编程语言 >详解C++完美转发

详解C++完美转发

时间:2024-07-06 16:43:28浏览次数:18  
标签:右值 t2 左值 C++ t1 详解 引用 && 转发

我们先来看折叠规则

引用折叠规则

在C++中,引用折叠规则的主要目的是为了保证在模板推导过程中,对于参数 T&& 能够正确地推导出其最终的引用类型,以便进行参数传递时的正确行为。下面是引用折叠规则的总结:

  1. 左值引用折叠

    • T& & 折叠为 T&
    • T& && 折叠为 T&

    这意味着如果一个左值引用被再次引用,或者一个左值引用被右值引用引用,最终的结果仍然是左值引用。就是左值怎么引用都是左值。

  2. 右值引用折叠

    • T&& & 折叠为 T&
    • T&& && 折叠为 T&&

    这意味着如果一个右值引用被左值引用引用,最终结果是左值引用;如果一个右值引用被右值引用引用,最终结果仍然是右值引用

了解了折叠规则后,我们来看个demo

template <typename F, typename T1, typename T2>
void flip2(F f, T1 &&t1, T2 &&t2)
{

    f(t1, t2);
}

这个函数模板接受三个参数,并将t1和t2作为f的参数进行调用,给出f的实现

void gtemp(int&& v1, int& v2)
{
    cout << v1 << " " << v2 << endl;
}

调用

int j = 99;
flip2(gtemp, 42, j);
cout << "j is " << j << endl;

得到报错

error C2664: “void (int &&,int &)”: 无法将参数 1 从“T1”转换为“int &&”

分析:42是一个右值对象,j是左值,在flip2中形参t1通过折叠规则推导知类型为右值引用,t2是左值引用,但是将t1作为f的参数时,它依旧是作为一个左值来用的,因此gtemp也就是f调用明显会出错它的第一个参数类型为右值引用,也就是说flip2函数内部把外部实参42作为其他函数的参数传递时,将其的类型给“修改了”,从右值变为左值,这当然不是我们所希望的,那么怎么解决呢?

std::forward<>()函数就是用来保持类型不变的。

再看修改demo

template <typename F, typename T1, typename T2>
void flip2(F f, T1 &&t1, T2 &&t2)
{
    f(std::forward<T1>(t1),std::forward<T2>(t2));
}

forward包含在utility库里,我们使用完美转发函数使t1,t2保持类型与外部实参一致,也就是42(右值),j(int)因此程序正常运行。

标签:右值,t2,左值,C++,t1,详解,引用,&&,转发
From: https://www.cnblogs.com/dwinternet/p/18287426

相关文章

  • Nuxt框架中内置组件详解及使用指南(一)
    title:Nuxt框架中内置组件详解及使用指南(一)date:2024/7/6updated:2024/7/6author:cmdragonexcerpt:本文详细介绍了Nuxt框架中的两个内置组件和的使用方法与功能。确保包裹的内容仅在客户端渲染,适用于处理浏览器特定功能或异步数据加载。而是一个实验性组件,用于在SSR过......
  • C++语言常见错误分析汇总
    在一个工程里出现两个main函数时3.obj:errorLNK2005:_mainalreadydefinedinfile1.objDebug/HELLO.exe:fatalerrorLNK1169:oneormoremultiplydefinedsymbolsfound这个就是说,你的main函数重定义了。你看看是不是你的工程里面,包含了很多个有main函数的文件?......
  • c++基础知识——常量和变量
    常量1.常量的性质在程序运行的过程中,其值不改变的量称为常量。常量分为两种:一类直接写出它的值,称为字面值常量,如123,'abc',true等;一类是使用const修饰的对象。2.整形字面值常量整形字面值常量采用我们平常使用的十进制整数表示。如138,0,-512等,都是整形常量,二18.1,32.6等不是整......
  • 【C/C++ new/delete和malloc/free的异同及原理】
    new/delete和malloc/free都是用于在C++(以及C语言在malloc/free的情况下)中动态申请和释放内存的机制,但它们之间存在一些显著的异同点。以下是对这两组函数/运算符的异同点的详细分析:相同点目的相同:两者都用于在堆(heap)上动态地分配和释放内存。手动管理:无论是new/delete还是......
  • 快速排序c++&&java代码实现
    快速排序的思想(基于分治法): 每次选一个基准元素x,通过一次遍历将排序表划分为独立的两部分a[l,k-1],a[k+1,r];其中左边的元素<=x,右边的1元素>x,然后递归下去,直到每个块的大小为1;c++#include<bits/stdc++.h>usingnamespacestd;voidquickSort(vector<int>&q,int......
  • java学习——基础语法篇(适合已经学过c++的人群)
    本篇适合之前学过c和c++语言,现在要学java的人进行学习。由于之前学习过c++同为面向对象的程序语言,基础语法在相对比之下学习,对比c++与java的差异,会快速掌握基本语法。学编程语言,语法不是重点,用时即查,编程思路才是重点。1.注释、标识符、关键字、数据类型,变量定义,运算符与c++基本......
  • 初始C++
    1.visualstudio2022创建项目以及创建C++文件完成上述步骤之后我们就可以敲代码了!!2.关于编译和链接1.ctrl+F7对当前C++文件进行编译并会在编译成功后生成.obj文件。2.F5运行整个项目就会将一个项目下的所有C++文件进行编译再将编译后生成的.obj文件链接起来生......
  • HTML【详解】超链接 a 标签的四大功能(页面跳转、页内滚动【锚点】、页面刷新、文件下
    超链接a标签主要有以下功能:跳转到其他页面<ahref="https://www.baidu.com/"target="_blank">百度</a>href:目标页面的url地址或同网站的其他页面地址,如detail.htmltarget:打开目标页面的方式_self:在同一个网页中显示(默认值)_blank:在新的窗口中打开【常用】_......
  • 【C++】认识使用string类
    【C++】STL中的string类C语言中的字符串标准库中的string类string类成员变量string类的常用接口说明成员函数string(constructor构造函数)~string(destructor析构函数)默认赋值运算符重载函数遍历string下标+[]迭代器范围for反向迭代器capacitysizelengthmax_sizeresi......
  • MySQL主从复制详解
    MySQL主从复制详解MySQL主从复制是数据库环境中常用的一种数据同步技术,用于实现数据的高可用性和负载均衡。通过主从复制,可以将一个MySQL数据库服务器的数据实时地复制到一个或多个从库中。本文将介绍MySQL主从复制的原理、配置步骤和常见问题。一、MySQL主从复制的原理M......