首页 > 其他分享 >万能引用

万能引用

时间:2024-03-30 21:11:06浏览次数:23  
标签:右值 int 万能 引用 && testfunc

右值引用用&&符号表示。右值引用主要是绑定到右值上,如:

int &&rv = 100;

看下面函数定义:

void myfunc(int &&tmprv) {
    cout << tmprv << endl;
    return;
}

int main() {
    myfunc(10); // 正确,右值作为实参
    int i = 100;
    myfunc(i); // 错误,右值引用不能接受左值
}

由此可知,右值引用肯定不能接受左值,现在将myfunc()函数改造成函数模板:

template<typename T>
void myfunc(T&& tmprv) {
    cout << tmprv << endl;
    return;
}

如果上面的T是int类型,那么函数myfunc()用int实例化后得到的函数似乎和普通的myfun()函数是一样的,但myfunc(i);并没有报错,因此推断T没有推断为int类型。

1. 万能引用

万能引用又称未定义引用,这种引用离不开两种语境:

  • 必须是函数模板;
  • 必须是发生了模板类型推断并且函数模板形参如T&&;

万能引用的格式如T&&,auto && tmpvalue = ...也是一个万能引用,其它的&&情况都是右值引用。

2. 万能引用资格的剥夺与辨认

剥夺:

const修饰词(前后)会剥夺一个引用成为万能引用的资格,被打回原型成为右值引用。

template<typename T>
void myfunc(const T&& tmprv) { // 有const存在,为右值引用
    cout << tmprv << endl; 
    return;
}

int main() {
    int i = 100;
    myfunc(i); // fault
}

辨认:

增加mytest类模板定义:

template<typename T>
class mytest{
pubic:
    void testfunc(T&& x) {} // 这不是万能引用,是右值引用
}

int main() {
    mytest<int> mc;
    int i = 100;
    mc.testfunc(i); // fault,左值不能绑定在右值引用上
}

为什么testfunc后面的T&&不是万能引用,而是一个右值引用,因为testfunc()成员函数本身并没有涉及类型推断,testfunc()成员函数是类模板mytest的一部分,首先得用以下语句实例化这个类模板的一个具体类:

mytest<int> mc;

实例完这个类之后,mytest<int>类存在了,那么testfunc()成员函数才真正存在,所以testfunc()成员函数存在的时候就已经为:

void testfunc(int&& x) {}

所以testfunc()函数本身没有涉及类型推断,这个x是右值引用。如果增加一个public修饰的成员函数模板:

template<typename T>
class mytestc {
public:
    void testfunc(T&& x) {} // 右值引用
    
    template<typename T2>
    void testfunc2(T2&& x) {} // 万能引用
};

int main() {
    mytestc<int> myoc;
    int i = 10;
    myoc.testfunc2(i); // 左值可以,右值10也可以
}

 

标签:右值,int,万能,引用,&&,testfunc
From: https://www.cnblogs.com/love-9/p/18106032

相关文章

  • 前端面试手写题目|编写一个函数,实现对象深拷贝,递归引用,日期,正则symbol健。手写Object.
    快速,选择,希尔45,编写一个函数,实现对象深拷贝,并解决递归引用,日期,正则表达式,对象中含有symbol健等问题。functiondeepCopy(obj,cache=newWeakMap()){if(obj==null||typeofobj!=='object'){r......
  • 实验报告( 重载,引用,指针,交换,字符串的连接 )
       一、实验目的:掌握函数重载的使用方法深入理解指针的概念,掌握指针的使用方法理解引用的概念,掌握引用作为函数参数的使用方法二、实验仪器或设备:微型计算机三、总体设计(设计原理、设计方案及流程等)实验内容:1、设计一组重载函数add(),至少包括:charadd(char,int);......
  • 练习-Java类和对象之对象引用之模拟手机功能
    第1关:练习-Java类和对象之对象引用之模拟手机功能任务描述本关任务:实现手机的基本功能。手机具有属性:品牌(brand)、型号(type)、价格(price)、操作系统(os)和内存(memory);具有功能:查看手机信息(about())、打电话(call(intnumber))、玩游戏(play())。编程要求仔细阅读右侧编辑区内给出的......
  • C++取经之路(其二)——含数重载,引用。
    含数重载:函数重载是指:在c++中,在同一作用域,函数名相同,形参列表不相同(参数个数,或类型,或顺序)不同,C语言不支持。举几个例子:1.参数类型不同intAdd(intleft,intright){ cout<<"intAdd(intleft,intright)"<<endl; returnleft+right;}doubleAdd(doublele......
  • Oracle查询数据库万能SQL
    Oracle数据库表简要说明数据库表描述USER开头的只能查询自身用户的表DBA开头的最高权限,只能用sys、system用户才能查询CDB开头的ContainerDatabase数据库容器,ORACLE12版本引入ALL开头的sys、system、普通用户都能查查询数据库表--查询数据......
  • 交叉引用时产生的乱码怎么处理
    写论文时碰见一个问题,就是交叉引用后出现的不是域结果而是域代码,看着很不舒服,应该咋办呢?鼠标右键可以切换域代码,但是每次改比较麻烦,最简单的方法是直接在Word里设置。打开word-------选择“文件”----------最下面选择“更多”--------“选项”,打开Word选项窗口;如图选择“......
  • Java ----- 静态、继承、引用类型使用
    面向对象最重要的两个概念:类和对象;类名的首字母大写,满足“驼峰写法”;一个Java代码文件中,可以定义多个类,但是只有一个类是public修饰的,而且public修饰的类名必须成为代码的文件名称;、类中的成分研究:类中有且仅有五大成分(五大金刚)1.成员变量(Field:描述类和对象的属性信......
  • java中的什么是值传递,什么是引用传递
    值传递(PassbyValue):值传递意味着在方法调用时,实际参数的值被传递给方法中的形式参数,即在方法内部修改形参的值不会影响实参的值。Java中的基本数据类型(如int、float、double等)就是值传递的典型例子。publicclassMain{publicstaticvoidmain(String[]args){......
  • 2.Vue中bootstrap的引用问题
    上来敲书上一个代码一个计划表生成了一下没生成样式看一下代码class有我们熟悉的bootstrap样式那加载不出来啊啊废话找人学习啊老师又不教vscode中vue使用bootstrap第一次参考https://www.jb51.net/javascript/296467tdi.htm选择项目加载啊哎哎哎报错了利用你的......
  • 【Java】Java中是值传递还是引用传递的?
    对于Java的初学者来说值传递和引用传递是一个容易混淆的概念,很多时候调用方法传入参数运行方法后的结果与自己享的不一致。那么Java到底是如何传参的呢?简介值传递:在值传递中,函数接收到的是参数的值的副本,而不是参数本身。当你向函数传递一个参数时,函数会创建一个新的变量......