临时变量作为非const的引用进行参数传递引发的编译错误
2015-08-25 09:55
351 查看
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<<str<<endl; } //如此调用会报上面描述的错误 print("hello world");
出错的原因是编译器根据字符串”hello world”构造一个string类型的临时对象,这个临时对象具有const属性。当这个临时对象传递给非const的string&引用类型时,因为非const引用绑定对象时,要求该对象也是非const对象。而在这时,因为string类型的临时对象是const对象,所以就出现错误。
结合引用的性质可知:
(1)能建立引用的表达式一定是左值;
(2)不能作为左值的表达式只能建立常引用。
因此,解决办法就是将print()函数的参数改为常引用。代码修改如下,可顺利通过编译。
void print(const string& str) { cout<<str<<endl; } //顺利通过编译 print("hello world");
通过以上代码,也可以看出Effective C++中倡导的一个C++的编程原则,即尽可能的使用const。因为这样可以使代码更为健壮,将错误暴露于编译阶段。
2.所有的临时对象都是const对象吗
为什么临时对象作为引用参数传递时,必须是常量引用呢?很多人对此的解释是临时对象是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。这个解释在关于理解临时对象不能作为非const引用参数这个问题上是可以的,但不够准确。更有甚者,认为所有的临时对象均是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; } //打印函数 void print(IntClass & intc) { cout<<intc<<endl; //通过引用修改这个临时对象 intc=8; cout<<intc<<endl; } int main(int argc,char* argv[]) { print(IntClass(6)); }
程序输出:
6
8
以上代正确编译运行,没有错误。IntClass(6)表示生成一个无名的临时对象,传递给非const引用,在print函数中通过引用修改了这个临时对象。这说明了并非所有的临时对象都是const对象。
那哪些临时对象是const对象,哪些临时对象不是const对象呢?这里贴上摘自网上的一句话:“内置类型产生的临时变量具有常性,而自定义类型产生的临时变量不具有常性”,我想这句话能解释你所谓的临时变量为什么能作为左值的原因。。”此话不知正确与否,但目前还没有发现其错误,待以后考证。
参考文献
[1]http://blog.sina.com.cn/s/blog_4cce4f6a0100piuv.html相关文章推荐
- HDU 2844+POJ 1014 +FZU 1432详解(多重背包&&二进制优化)
- POJ 3126 Prime Path (BFS)
- 揭秘谷歌网络基础设施十年演变过程
- vijos1098:合唱队形
- 5.5 运算符问题
- zzuli训练赛_05_13-K
- poj-1426(转)
- 转贴 poj分类
- 转贴 poj分类
- poj-1321
- 解决 ffmpeg yasm not found, use --disable-yasm for a crippled build
- nyoj--水池数目
- nyoj--图像有用区域
- XML(学习笔记)
- cocos2d js layer定义扑克放在scene中,修改layer中图片,layer响应点击函数
- Java从入门到精通(实例版) 例9.11访问构造方法
- css样式学习笔记
- Request(对象)
- sql一些错误修改的总结
- 转载(如何学习C#)