文章目录

  • 1.认识临时变量的常量性
  • 2.临时变量常量性的原因
  • 参考文献

1.认识临时变量的常量性

关于临时变量的常量性,先看一段代码。

void print(string& str) {cout<<str<<endl;
}
//如此调用会报编译错误
print("hello world");

在Linux环境使用g++编译,会出现: invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type 'std::string’的错误。其中文意思为临时变量无法为非const引用初始化。出错的原因是编译器根据字符串"hello world"构造一个string类型的临时对象,这个临时变量具有const属性,当这个临时变量传递给非const的string&引用类型时,无法隐式完成const到非const的类型转换,便出现上面的编译错误。解决办法是将print()函数的参数改为常引用。代码修改如下,可顺利通过编译。

void print(const string& str) {cout<<str<<endl;
}
// 顺利通过编译
print("hello world");

通过以上代码,可以看出在设计函数时,形参尽可能地使用const,这样可以使代码更为健壮,将错误暴露于编译阶段。

2.临时变量常量性的原因

为什么临时对象作为引用参数传递时,形参必须是常量引用呢?很多人对此的解释是临时变量是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。这个解释在理解临时变量不能作为非const引用参数这个问题上是可以的,但不够准确。事实上,临时变量是可以作为左值(Lvalue) 并被赋值的,请看下面的代码:

class IntClass {private:int x;
public:IntClass(int value):x(value){}friend  ostream& operator<<(ostream &os, const IntClass &intc);
};// 重载operator<<
ostream& operator<<(ostream &os, const IntClass &intc) {os<<intc.x;return os;
}int main(int argc,char* argv[]) {cout << (IntClass(6) = IntClass(8))<<endl;
}

程序输出:

8

以上代码正确编译运行,没有错误。IntClass(6)表示生成一个无名临时变量并作为左值被修改,所以临时变量并不是常量,只是编译器从语义层面限制了临时变量传递给非const引用。注意,这里与《C++编程思想》在第八章中的“临时量”小节中认为“编译器使所有的临时量自动设为const”的说法有些不同。

那编译器为何作出如此限制呢?如果一个实参以非const引用传入函数,编译器有理由认为该实参会在函数中被修改,并且这个被修改的引用在函数返回后要发挥作用。但如果把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,临时变量所在的表达式执行结束后,临时变量就会被释放,所以,一般说来, 修改一个临时变量是毫无意义的,据此,C++编译器加入了临时变量不能作为非const引用实参这个语义限制,意在限制这个非常规用法的潜在错误。


参考文献

[1] c++中临时变量不能作为非const的引用参数
[2] C++编程思想[M].刘宗田译.C8.3.2.1临时量

C++ 临时变量的常量性相关推荐

  1. C++11 右值引用与常量左值引用保存临时变量(函数返回值)的底层分析

    右值引用保存临时变量(函数返回值)的问题 :临时变量是右值 1.普通变量接收函数返回值: 2.右值引用变量接收函数返回值: 3.用const int& 和右值引用是一样的效果,只是const ...

  2. C++,创建临时变量传递给参数为常量的函数,lvalue与rvalue的转换。

    在开始之前,先来看一个例子 void func(const int& a); int main() {int b=1;func(b*2); //正常运行func(2); //报错 } 首先,注 ...

  3. Windows客户端C/C++编程规范“建议”——变量和常量

    8 变量和常量 8.1 尽量不要使用全局变量 等级: [要求] 说明:全局变量的滥用和goto的滥用一样,都是一种灾难.它将使得逻辑变得难以调试和控制. 8.2 不涉及外部使用的全局变量需要使用sta ...

  4. 临时变量不能作为非const引用

    int func(a) {return a; }int main() {int r = func(3 + 5);return 0; } 上述代码报错, 非常量引用的初始值必须为左值 .  主要原因如下 ...

  5. ABAP 中的变量和常量

    ABAP 程序由数据和逻辑组成.其中数据包含变量和常量. ABAP 变量 所谓变量,就是其存储值在程序生命周期内可以改变的量. 如下图第8,9行的lv_1和lv_2. 我们在第11行和第13行分别给变 ...

  6. python中的常量可以修改吗_深入理解Python变量与常量

    变量是计算机内存中的一块区域,变量可以存储规定范围内的值,而且值可以改变.基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中.常量是一块只读的内存区域,常量一旦被初始化就不能被 ...

  7. Golang——变量和常量详解

    变量: 变量是在程序运行过程中,其值可以发生改变的量,是数据的存储空间,作为静态类型语言,Go变量有固定的数据类型,类型决定了变量内存的长度和存储格式.我们只能修改变量值,无法改变类型. 变量名: 因 ...

  8. JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)...

    Java基础语法(变量.常量.数据类型.运算符与数据类型转换) 1.变量 Java中.用户能够通过指定数据类型和标识符来声明变量.其基本的语法为: DataType identifier; 或 Dat ...

  9. Go语言学习十二 变量和常量

    本文最初发表在我的个人博客,查看原文,获得更好的阅读体验 Go 使用var关键字声明变量:使用关键字const声明常量.变量可以像常量一样初始化. 一 变量 1.1 变量声明 语法: var 变量名 ...

最新文章

  1. a href=#与 a href=javascript:void(0) 的差别
  2. Linux下修改python pip镜像源:推荐豆瓣源
  3. 网络编程-之粘包现象
  4. 庖丁解牛看委托和事件(续)
  5. 学习python第十天
  6. 解题报告——习题2-5 分数化小数(decimal) 输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。
  7. nodejs 读取excel文件,并去重
  8. 武汉大学c语言实验报告模板,武汉大学C语言程序设计第3讲(2012级).ppt
  9. Java菜鸟教程 递归算法与Scanner类
  10. 制图综合:河流水系提取简化
  11. Docker cgroups资源控制
  12. 鼠标划过切换div显示
  13. Android10.0应用图标隐藏方案(7.0-10.0)
  14. w ndows10更改浏览器,win10电脑修改默认浏览器的三种方法
  15. 联想 thinkpad usb 移动硬盘 u盘 BIOS 启动 ubuntu 系统
  16. SQLServer从mdf和ldb还原数据库
  17. 什么是RESTful风格的API设计?
  18. 基于springboot的高校疫情打卡上报系统设计与实现 文档+项目源码及数据库文件+演示视频
  19. Windows--cygwin
  20. VMware 虚拟SCSI、SATA 和 NVMe 存储控制器条件、限制和兼容性

热门文章

  1. 云安全之虚拟机安全监控
  2. PacketSender —— TCP/UDP 包测试工具
  3. MySql 1067错误
  4. GCD之后台程序运行
  5. 高效访问Internet-启用ISA Server的缓存
  6. 蓝桥杯 ADV-155 算法提高 上帝造题五分钟
  7. 蓝桥杯 ADV-184 算法提高 素数求和
  8. 蓝桥杯 ADV-77 算法提高 统计平均成绩
  9. 可以看游资的app_大大游资软件下载
  10. 观电影《头号玩家》有感