首页 > 代码库 > c++中临时变量不能作为非const的引用参数

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引用的这个语义限制,意在限制这个非常规用法的潜在错误。

 

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