c++中临时变量不能作为非const的引用参数

试看下面的代码:

#include <iostream>

using namespace std;

void f(int &a)

{

cout << "f(" << a  << ") is being called" << endl;

}

void g(const int &a)

{

cout << "g(" << a << ") is being called" << endl;

}

int main()

{

int a = 3, b = 4;

f(a + b);  //编译错误,把临时变量作为非const的引用参数传递了

g(a + b);  //OK,把临时变量作为const&传递是允许的

}

上面的两个调用之前,a+b的值会存在一个临时变量中,当把这个临时变量传给f时,由于f的声明中,参数是int&,不是常量引用,所以产生以下编译错误:

而在g(a+b)中,由于g定义的参数是const int&,编译通过。   问题是为什么临时变量作为引用参数传递时,必须是常量引用呢?很多人对此的解释是临时变量是常量,不允许赋值,改动,所以当作为非常量引用传递时,编译器就会报错。这个解释在关于理解临时变量不能作为非const引用参数这个问题上是可以的,但不够准确。事实上,临时变量是可以被作为左值(LValue)并被赋值的,请看下面的代码:

#include   <iostream>

using namespace std;

class CComplex {

friend CComplex operator+(const CComplex &cp1, const CComplex &cp2);

friend ostream& operator<<(ostream &os, const CComplex &cp);

private:

int x;

public:

CComplex(){}

CComplex(int x1) {

x = x1;

}

};

CComplex operator+(const CComplex &cp1, const CComplex &cp2)

{

CComplex cp3;

cp3.x = cp1.x + cp2.x;

return cp3;

} ostream& operator<<(ostream &os, const CComplex &cp)

{

os << cp.x;

return os;

}

int main()

{

CComplex a(2), b(3), c(4);

cout << (a + b) << endl;

cout << ((a + b) = c) << endl;   //临时对象作为左值

return 0;

}

上面的程序编译通过,而且运行结果是:

5

4

临时变量确实被赋值,而且成功了。

所以,临时变量不能作为非const引用参数,不是因为他是常量,而是因为c++编译器的一个关于语义的限制。如果一个参数是以非const引用传入,c++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果你把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制,意在限制这个非常规用法的潜在错误。

时间: 2024-10-09 15:57:04

c++中临时变量不能作为非const的引用参数的相关文章

临时变量作为非const的引用进行参数传递引发的编译错误

1.错误原因即解决办法 Linux环境运行,使用g++编译,观察如下代码,会出现: invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'std::string'的错误. 其中文意思为临时变量无法为非const的引用初始化.也就是在参数传递的过程中,出现错误.出错的代码如下: void print(string& str) { cout<<st

学号20175313 《程序设计中临时变量的使用》第八周

目录 程序设计中临时变量的使用 一.题目要求 二.运行结果截图 三.遇到的问题及其解决方法 四.代码链接 五.心得体会 程序设计中临时变量的使用 一.题目要求 //定义一个数组,比如 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int i:arr){ System.out.print(i + " "); } System.out.println(); // 添加代码删除上面数组中的5 ... //打印出 1 2 3 4 6 7 8 0 f

20175314薛勐 程序设计中临时变量的使用(课下测试,选做)

程序设计中临时变量的使用(课下测试,选做) 要求 定义一个数组:int arr[] = {1,2,3,4,5,6,7,8}; 打印原始数组的值:for(int i:arr){System.out.print(i + " "); } System.out.println();// 添加代码删除上面数组中的5 ... 打印出 1 2 3 4 6 7 8 0:for(int i:arr){System.out.print(i + " ");} System.out.pri

C++参数传递(引用,临时变量)

一般的变量声明时就创建相应的内存空间,该空间用于存储该变量的值.函数进行按值传递时,是将该变量值的拷贝传给函数,因此在函数中将传进来的值改变也不能改变变量的值. 指针变量和按指针传递.指针类型的变量在声明后,根据操作系统的不同创建相应大小的内存空间,该空间上存储的是一个地址,该地址指向一个变量.如果函数按指针进行传递参数,也是将变量的拷贝传进来,但该变量是一个指向某内存单元的地址,对该变量进行解引用操作,改变其内存单元存储的值,即可改变变量解引用后的值. 引用和按引用传递.引用是变量的别名.在声

C++11引用临时变量的终极解析

工作中遇到一个引用临时变量的问题,经过两天的学习,私以为:不仅弄明白了这个问题,还有些自己的独到见解. 这里使用一个简单的例子来把自己的学习过程和理解献给大家,如果有什么问题请不吝指正. *************************Code************************* class Dog { public: Dog(){} virtual ~Dog(){} }; void NonConstReference (Dog & dog ) { //tell the dog

C++函数返回引用、非引用以及临时变量的问题

C++中新增了引用类型,所以函数的返回值可以是引用类型.那么就会有人想问 返回引用类型与返回非引用类型有区别吗? 结论是显然的,而且有明显的区别.尤其初学者会很容易绕进去.让我们先看四个函数原型.以int类型来举例 (1) int fun(...) { return ....//后面跟的是一个引用 } 例如:int fun(int &a) { return a; } (2)int fun(...) { return....//后面跟的是一个非引用 } 例如:int  fun(int a) { r

C++标准的规定:非常量的引用不能指向临时对象(转载)

C++标准的规定:非常量的引用不能指向临时对象: 为了防止给常量或临时变量(只有瞬间的生命周期)赋值(易产生bug),只许使用const引用之. 下面的内容转自: http://blog.csdn.net/liuxialong/article/details/6539717 概括一下: 不能把临时对象作为实参传给非const引用. 例如: void conv(string &str) { } int main() { conv("dasd"); // 这里错了,编译器自动生成一

第2章 重新组织函数(3):引入解释性变量、分解临时变量和移除对参数的赋值

5. 引入解释性变量(Introduct Explaining Variable) //引入解释性变量 //重构前 if((platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize > 0) { //do somethin

[转] C++临时变量的生命周期

http://www.cnblogs.com/catch/p/3251937.html C++中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量. 主要的用途主要有两类: 1) 函数的返回值, 如: 1 string proc() 2 3 { 4 5 return string("abc"); 6 7 } 8 9 10 11 int main() 12 13 { 14 15 proc(); 16 return 0; 17 18 } 其中第15行会产生一个临时变量.但并不