zoukankan      html  css  js  c++  java
  • 临时变量不能作为非const类型引用形参的实参

    摘要:

         非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/

  • 相关阅读:
    C++各大有名库的介绍——网络通信
    C++名人的网站
    C++各大有名库的介绍——序列化
    C++各大有名库的介绍——字符串
    C++各大有名库的介绍——游戏开发
    C++各大有名库的介绍——其他库
    C++各大有名库的介绍——综合
    java hashcode写法
    vs 在线引用
    eclipse去掉拼写检查
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3681224.html
Copyright © 2011-2022 走看看