摘要:

    非const 引用形参只能与完全同类型的非const对象关联。

     具体含义为:(1)不能用const类型的对象传递给非const引用形参;

                   (2)实参类型必须与非const引用形参的类型完全一致,例如,不可以将一个float对象传给 double &类型的引用形参;

                       (3)不能将一个右值类型的实参 传递给 非const引用形参。

  

      建议:在不需要修改实参的值的前提下,尽量使用const 限定的引用作为形参。

C++中的引用传参是给实参起了一个别名,这种参数传递方法称为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。
但是如果函数的实参是一个表达式而不是一个左值的时候,会发生什么情况呢。
如果有一个函数:

double square(const double &ra) {
return ra * ra;
}

如果试图使用square(x + 3.0)这样的调用,将发生什么情况呢?在现代版本的C++中,这是错误的,有些编译器将指出这一点;有些编译器将发出这样一个警告:

Warning: Temporary used for parameter 'ra' in call to square(double &)

因为早期的C++确实允许将表达式传递给引用变量。那么,它的实现方式是:x+3.0不是double类型的变量,因此程序将创建一个临时的无名变量,并将其初始化为表达式x+3.0的值。然后,ra将成为该临时变量的引用。下面详细看看这种情况:
如果实参与引用参数不匹配,C++将生成临时变量。现在,仅当参数为const引用时,C++才允许这样做,但是这是一种新的限制。它会在以下两种情况下生成临时变量:

  • 实参的类型正确,但不是左值。
  • 实参的类型不正确,但可以转换为正确的类型。

左值是可被引用的数据对象,例如,变量、数组元素、结构成员、引用和被解除引用的指针都是左值。非左值包括字面常量和包含多项的表达式。对于函数:

double square(const double &ra) {
return ra * ra;
}

现在考虑如下代码:

double side = 3.0;
double *pd = &side;
double &rd = side;
long edge = 5L;
double lens[4] = {2.0, 3.0, 4.0, 5.0};
double c1 = square(side); //ra is side
double c2 = square(lens[2]); //ra is lens[2];
double c3 = square(rd); //ra is rd is sizd
double c4 = square(*pd); //ra is *pd is side
double c5 = square(edge); //ra is temporary variable
double c6 = square(7.0); //ra is temporary variable
double c7 = square(side + 7.0) //ra is temporary variable

参数side, lens[2], rd, *pd都是有名称的、double类型的数据变量,因此可以创建引用。但是,edge属于不同类型的变量,7.0是常量类型,side+7.0属于表达式,在这几种情况下编译器都会生成一个临时变量,并让ra引用它。
C++允许常量引用对于这种行为(建立临时变量),是因为该函数的目的是使用传递的值,而不是修改它们,因此创建临时变量不会造成任何不利的影响,反而会使函数在可处理的参数种类方面更通用。实际上,对于形参为const引用的C++函数,如果实参不匹配,刚其类似于按值传递,为确保原始数据不改变,使用临时变量来存储值。

Reference

[1] <C++ premier >中文版第四版 7.2.2节

[2] 引用传参、临时变量和const  http://gzxabcdefg.blog.163.com/blog/static/2345179420118308105747/

临时变量不能作为非const类型引用形参的实参的更多相关文章

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

    转自:http://blog.csdn.net/u011068702/article/details/64443949 1.看代码 2.编译结果 3.分析和解决 就拿f(a + b)来说,a+b的值会 ...

  2. 非const引用参数传入不同类型编译不过的理解(拒绝将临时对象绑定为非const的引用的形参是有道理的)

    int f (int & I) { cout<<I<<std::endl; } void main() { long L; f(L); // 编译不过 f((int)L ...

  3. const变量指针赋值给非const类型的指针运行结果

    在c++可以定义一个const变量,然后把变量的值赋给一个非const指针,可以通过指针来改变const变量的值吗?下面的截图给出了答案

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

    工作中遇到一个引用临时变量的问题,经过两天的学习,私以为:不仅弄明白了这个问题,还有些自己的独到见解. 这里使用一个简单的例子来把自己的学习过程和理解献给大家,如果有什么问题请不吝指正.   **** ...

  5. const类型总结

    const 表示常类型   作用: 1.具有不可变性.   2.可以很方便对参数进行调整和修改,和宏定义一样,不变则已,变都变.   3.保护被修饰的东西,防止被意外修改.(如:在修饰函数的形参时,加 ...

  6. C++临时变量的生命周期

    C++ 中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量.主要的用途主要有两类: 1) 函数的返回值, 如: string proc() { return string(" ...

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

    http://www.cnblogs.com/catch/p/3251937.html C++中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量. 主要的用途主要有两类: 1) 函数的 ...

  8. 非const引用不能指向临时变量

    没找到具体原因,MSDN看到下面这句,VC是从2008才有这一限制的,感觉就是从语法上对临时变量增加了限定,因为一般说来修改一个临时变量是毫无意义的,通过增加限定,强调临时变量只读语义.虽然实际上修改 ...

  9. C++-const_cast只能用于指针和引用,对象的const到非const可以用static_cast

    Static_cast可以对对象也可以对指针也可以对引用,但是const_cast只可以对指针和引用使用,后者不可以对对象用,如果你要把一个const值转化为非const值只能用隐式执行或通过使用st ...

随机推荐

  1. Java for LeetCode 218 The Skyline Problem【HARD】

    A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...

  2. Django~Models1

    不用数据库不用Models 省却 --------------- startapp urls +链接 view以下 ---------------- 添加Model 在project/settings ...

  3. Greedy:Linear world(POJ 2674)

      Linear world 题目大意:一些人生活在线性世界中,到达线性世界两端就会消失,两个人的前进方向有两个,相遇会改变各自相遇方向,求最后一个人掉下的人的名字和时间. 其实这一题就是弹性碰撞的模 ...

  4. codeforces 501C. Misha and Forest 解题报告

    题目链接:http://codeforces.com/problemset/problem/501/C 题目意思:有 n 个点,编号为 0 - n-1.给出 n 个点的度数(即有多少个点跟它有边相连) ...

  5. CSS3实现元素旋转

    -webkit-transform:rotate(30deg); 参数代表顺时针自旋转角度 这个元素还提供了文本倾斜的方法 - HTML5与CSS3 P299

  6. 20145213《Java程序设计》实验二Java面向对象程序设计实验报告

    20145213<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装,继承,多态 初步掌握UML建模 熟悉S.O. ...

  7. IOS- 堆和栈 详解

    Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就 ...

  8. August 12th 2016 Week 33rd Friday

    Everything is good in its season. 万物逢时皆美好. Every dog has its day. You are not in your best condition ...

  9. vs c# int & int32

    在vs c#中,int就等价于int32, 所以通常也是使用int32 当在统计总数时,最好使用int32,int16数值范围太小,如果超出,就会变成随机数.

  10. 安装less

    1.下载安装iterm(http://www.iterm2.com/) 2.打开iterm,输入 sudo npm install -g less