当前位置: 首页 > news >正文

int c =5; 代码解释


author: hjjdebug
date: 2025年 05月 27日 星期二 15:24:58 CST
descrip: int &&c =5; 代码解释


文章目录

  • 1. c 的类型是右值引用.
  • 2. c 的值类型是左值引用
  • 3. 为什么会有这样的设计?
  • 4. 总结:
  • 5. 测试代码:

int &&c =5;
这么简单的代码, 竟不知有这么多内涵.

变量c 有两种身份, 类型和值类型.

1. c 的类型是右值引用.

因为c 被声明为 int &&, 所以类型是右值引用. 它只能bind到右值,这里bind到5
类型是右值的用途:

  1. 绑定临时对象,延长其生命周期(例如 5 是字面量,临时存在,但 c 将其生命周期延长到自己的作用域)
  2. 实现移动语义高效转移资源,(例如 std::vector 的数据所有权)
  3. 支持完美转发(std::forward)

2. c 的值类型是左值引用

所有具名变量(包括右值引用变量)在表达式中使用时,值类型均是左值。
左值的特征:
有名称(如 c 是变量名)
可以取地址(如 &c)
可以多次修改(如 c = 10)

3. 为什么会有这样的设计?

分离类型和值类别的意义?
右值引用的类型 (int&&) 是为了让编译器知道变量引用绑定到了右值.
而值类别(左值)是为了保证后续使用的安全性。
如果右值引用变量自动作为右值(连值类别也为右值),可能导致意外的资源转移:
例如:
str::string str=“I am a string”;
str::string &&s=str; // 此是s"值类型"是左值,类型是右值, 假如此时s 值类型自动变为右值.
use(s); //纯种右值,s的资源就可以被转移, 这样str的资源也就变成空了,谁要是用str就倒霉了,引起了混乱.
因此,具名的右值引用变量会被视为左值,避免隐式的资源转移,保证使用时的安全性

如果你确实想把值类别改为右值引用,可以用std::move()或static_cast()显式转换.

4. 总结:

类型是右值引用(int&&):表示 c 只能绑定到右值(如 5)
使用时是左值:因为 c 是具名变量,可以安全地多次访问和修改,避免隐式资源转移。
若要恢复右值属性: 需通过 std::move© 或 static_cast<int&&>© 显式转换。
完美转发转发的是"类型"而不是"值类型". 因为当前值类型都是据名左值引用.
而类型需要计算一下,是它父辈的类型传过来的.

说了半天,没有例子就是空谈.
给个例子吧.

5. 测试代码:

$ cat main.cpp 
#include <stdio.h>
#include <utility>template <typename T>
void printType(T&& arg,const char *str)  //万能引用
{printf("%-16s: ",str);//编译器是知道引用类型的if (std::is_lvalue_reference<decltype(arg)>::value){printf("Left value reference\n");}else if (std::is_rvalue_reference<decltype(arg)>::value){printf("Right value reference\n");}else{printf("I think this won't happen!\n");}
}int main()
{int &&c=5;printType(c,"c value type"); // c的值类型是左值引用, printType(std::forward<decltype(c)>(c),"c type"); //c的类型是右值引用
//	printType(std::move<decltype(c)>(c)); //error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’
//	int &a=5; //error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’     int &a = c;printType(a,"a value type"); //a的"值类型"是左值引用printType(std::forward<decltype(a)>(a),"a type"); //a的"类型"是左值引用printType(std::move<decltype(a)>(a),"a move type"); //强制转化为右值引用return 0;
}

std::forward<decltype©, 可以获取到c的类型, 而c仅代表值类型, 这是本代码的核心之处.
而c的类型实际是从父辈那得到的.
为什么这样可以获取,背后的逻辑是什么,我就不多解释了,可看另一篇博客.
https://blog.csdn.net/hejinjing_tom_com/article/details/148253757?spm=1001.2014.3001.5501

执行结果:
$ ./tt
c value type : Left value reference
c type : Right value reference
a value type : Left value reference
a type : Left value reference
a move type : Right value reference

http://www.xdnf.cn/news/678745.html

相关文章:

  • 《计算机组成原理》第 5 章 - 输入输出系统
  • 冒泡排序:像煮汤一样让数字「冒泡」
  • centos7安装MySQL(保姆级教学)
  • Linux信号量(32)
  • 鸿蒙OSUniApp 开发的滑动图片墙组件#三方框架 #Uniapp
  • 方正字库助力华为,赋能鸿蒙电脑打造全场景字体解决方案
  • 如何验证 AXI5 原子操作
  • leetcode刷题日记——完全二叉树的节点个数
  • Java怎么实现父子线程的值传递?InheritableThreadLocal类和transmittable-thread-local类?
  • Unity3D仿星露谷物语开发53之库存管理页面
  • Introduction to SQL
  • 【键盘说明书备份】ENERGYFORT
  • 编程日志5.27
  • MySQL :MySQL基本概念
  • 高性能计算 | 硅光芯片代工厂揭秘——技术特点与未来演进
  • SpringBoot集成jwt,实现token验证
  • 鸿蒙OSUniApp 实现自定义的侧边栏菜单组件#三方框架 #Uniapp
  • SQLord: 基于反向数据生成和任务拆解的 Text-to-SQL 企业落地方案
  • CMake 在尝试下载 Boost 时失败:SHA256 校验和与预期值不匹配
  • 【第1章 基础知识】1.8 在 Canvas 中使用 HTML 元素
  • 力扣HOT100之回溯:131. 分割回文串
  • 基于Matlab实现各种光谱数据预处理
  • Turf.js:前端地理空间分析的瑞士军刀
  • 2025山东CCPC补题
  • 基于Python的简易聊天机器人实现:从原理到实践
  • 组合API-provide和inject函数
  • 多模态机器学习
  • Android 开发:从 View Activity 向 Compose Activity 传递数据的多种实现方式
  • [yolov11改进系列]基于yolov11引入可改变核卷积AKConv的python源码+训练源码
  • QCustomPlot设置曲线图中文字缩放大小