首页 > 编程语言 >c++引用折叠

c++引用折叠

时间:2023-04-27 16:36:52浏览次数:49  
标签:右值 int 折叠 左值 c++ 引用 &&

目录

 

一、引用折叠

二、示例解析

三、参考:

 

一、引用折叠

     由于存在T&&这种万能引用类型,当它作为参数时,有可能被一个左值引用或右值引用的参数初始化,这是经过类型推导的T&&类型,相比右值引用(&&)会发生类型的变化,这种变化就称为引用折叠。

1.所有右值引用折叠到右值引用上仍然是一个右值引用。(A&& && 变成 A&&)

2.所有的其他引用类型之间的折叠都将变成左值引用。 (A& & 变成 A&; A& && 变成 A&; A&& & 变成 A&)

二、示例解析

       要说引用折叠,首先得说右值引用(在看这个之前需要了解C++11中左值,右值的概念)。它是C++11出现的新概念,声明类型的方法是:T&&,具体信息可以看下面的代码:

Class A

{

    A()

    {// do something}

};

 

A GetA()

{

    return A();

}

 

int main()

{

    A a1 = GetA();   // a1是左值

    A&& a2 = GetA(); // a2是右值引用

    return 0;

}

      a1是左值,在构造时使用了GetA() 产生的临时对象,之后GetA()产生的临时对象会销毁。

      a2是右值引用,其指向的就是GetA()所产生的对象,这个对象的声明周期是和a2的声明周期是一致的。即少了临时对象,从而省去了临时对象的构造和析构。

     由此可见右值引用的好处,在新代码中,右值引用是值得大力使用的。但是,在使用的时候,有例外情况了:T&&并不是一定表示右值,比如,如果它绑定的类型是未知的话,既可能是左值,又可能是右值。比如:

 

template<typename T>

void f(T&& param)

{

  std::cout<<param;

}

 

f(10); // 10是右值   int &&

int x = 10;

f(x);  // x是左值   int &

      以上这种万能引用类型(param的类型)能万能引用不同类型的参数,这种类型必须被初始化,而它是左值还是右值则取决于它的初始化,如果被左值初始化,那么它就是左值,反之亦然。那么什么时候是左值,什么时候是右值,就需要进行类型推导才知道。

       有的人会问,我传入的是一个左值a,并不是一个左值引用,为什么编译器会推导出T 为int &呢。首先,模板函数参数为 T&& param,也就是说,不管T是什么类型,T&&的最终结果必然是一个引用类型。如果T是int, 那么T&& 就是 int &&;如果T为 int &,那么 T &&(int& &&) 就是&,如果T为&&,那么T &&(&& &&) 就是&&。很明显,接受左值的话,T只能推导为int &。

     总结一下,万能引用就是利用模板推导和引用折叠的相关规则,生成不同的实例化模板来接收传进来的参数。

三、参考:

https://www.zhihu.com/question/40346748/answer/88672920

引用折叠和完美转发 - 知乎

 

from:https://blog.csdn.net/kupepoem/article/details/119944958

 

标签:右值,int,折叠,左值,c++,引用,&&
From: https://www.cnblogs.com/im18620660608/p/17359289.html

相关文章

  • [C++11]左值、右值、左值引用、右值引用小结
     左值和右值左值:指表达式结束后依然存在的持久对象,可以取地址,具名变量或对象右值:表达式结束后就不再存在的临时对象,不可以取地址,没有名字。比如inta=b+c;,a就是一个左值,可以对a取地址,而b+c就是一个右值,对表达式b+c取地址会报错。C++11中右值又由两个概念组成:将亡值和纯......
  • 条款28.理解引用折叠
     理解引用折叠以下面这个模板为例template<typenameT>voidfunc(T&&param);12模板形参T的推导类型中,会把传给param的实参是左值还是右值的信息给编码进去。编码机制是直截了当的:如果传递的实参是个左值,T的推导结果就是个左值引用类型;如果传递的实参是个右值,T的推导结......
  • C++ inline
    在C++中,inline关键字用于建议编译器将函数内联到调用它的地方。内联函数是一种优化技术,可以减少函数调用的开销。当一个函数被声明为内联时,编译器会尝试将函数的代码直接嵌入到每个调用该函数的地方,从而避免了函数调用时产生的额外开销,如保存寄存器、设置栈帧等。需要注意的是,inl......
  • 【C++】引用、引用初始化、引用折叠规则
     引用引用就好像存储数据的一块内存区域(变量)的一个名字,定义引用就好像声明了一个变量名并把它绑定到已存在的变量上,变量名附带属性(包括但不限于类型、存储期),变量名附带的属性由声明变量名时使用的声明指定符决定。需要注意的是,用于声明左值引用的&和用于声明右值引用的&&不......
  • 开心档之C++ 预处理器
    C++预处理器预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是C++语句,所以它们不会以分号(;)结尾。我们已经看到,之前所有的实例中都有 #include 指令。这个宏用于把头......
  • 开心档之C++ 多态
    C++多态多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。下面的实例中,基类Shape被派生为两个类,如下所示:实例#include<iostream>usingnamespac......
  • 开心档之C++ 引用
    C++引用引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。C++引用vs指针引用很容易与指针混淆,它们之间有三个主要的不同:不存在空引用。引用必须连接到一块合法的内存。一旦引用被初始......
  • 开心档之C++ STL 教程
    C++STL教程在前面的章节中,我们已经学习了C++模板的概念。C++STL(标准模板库)是一套功能强大的C++模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。C++标准模板库的核心包括以下三个组件:组件描述容......
  • c++打卡第十七天
    一、问题描述二、设计思路①、对于每个小孩得所得到的糖果数我们可以定义一个数组存储它们。②、需要进行循环结构,同时循环停止的条件为10个小孩得糖果数相同。③、小孩所得得糖果为奇数时需要向老师要一块后才再次分一半给后一个小朋友,这时候我们需要选择结构来实现。④、我们......
  • C++ linux epoll并发服务器模型初探
    socket通讯流程图最简单的可以通讯的C++服务器端代码:#include<stdio.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>#include<netinet/in.h>#defineSERV_PORT8000intmain(void){intlfd......