【问题标题】:Why int& r = 0 is illegal while const int& r = 0 is legal?为什么 int& r = 0 是非法的,而 const int& r = 0 是合法的?
【发布时间】:2015-12-30 07:40:38
【问题描述】:

我是 C++ 新手。我正在尝试学习 const 的概念。有人可以告诉我为什么第一个声明是非法的,而第二个是合法的?

int i = -1, &r = 0;         

const int i = -1, &r = 0;  

【问题讨论】:

  • @Zeta:建议的 dup 说 “C++ 不允许:int &ref = 7; 因为这不合逻辑,” - 所以对于 OP,这里有问题 - “为什么第一个是非法的,而第二个是合法的” - 很明显,没有被问到。另一个问题是关于const 的引用,而不是与非const 的对比。

标签: c++ pointers reference constants


【解决方案1】:

i 是一个红鲱鱼,问题是 int &r = 0;const int &r = 0;

非常量左值引用必须直接绑定到左值。 0 不是左值,所以 int &r = 0; 失败。

一个 const 左值引用可以绑定到一个右值。发生这种情况时,它不会直接绑定。相反,创建一个临时的(此处为const int 类型)并从右值复制初始化。借助此绑定,临时对象的生命周期得以延长。

所以const int &r = 0; 是合法的,并且与const int __temp = 0; const int &r = __temp; 具有相似的效果

【讨论】:

  • 注意:我故意用双下划线表示这是伪代码
【解决方案2】:

int i = -1, &r = 0; 等同于:

int i = -1;
int &r = 0; 

这里的问题是你不能写int &r = 0;,因为引用的初始化需要初始化器是一个左值(一个对象的地址 你可以接受),而文字 0 不是。

但是 const 引用的初始化器不必是左值,所以const int &r = 0; 就可以了。

【讨论】:

    【解决方案3】:

    i = -1, 位创建了一个初始化为-1i 变量,但对后面的引用没有影响,所以让我们关注:

    int &r = 0;      // illegal
    const int &r = 0;
    

    const int& 版本所做的是延长它所绑定的值的生命周期:换句话说,0 值通过r 保留以供使用,直到@987654329 的范围结束@ 已定义。

    很容易指出,同样的慷慨并没有扩展到int& 版本“因为它不是左值”为什么这个更有趣的问题在C++ FAQ进行了讨论:

    在 C++ 中,非 const 引用可以绑定到左值,而 const 引用可以绑定到左值或右值,但没有什么可以绑定到非 const 右值。这是为了保护人们不改变在新值可以使用之前被破坏的临时值的值。例如:

    void incr(int& a) { ++a; }
    int i = 0;
    incr(i);    // i becomes 1
    incr(0);    // error: 0 is not an lvalue
    

    如果允许该 incr(0) 或者一些没有人见过的临时值将被递增,或者更糟糕的是,0 的值将变为 1。后者听起来很傻,但实际上在早期的 Fortran 中存在类似的错误留出一个内存位置来保存值 0 的编译器。

    【讨论】:

    • 自 C++11 以来,我们有 int&&r = 0;,它是合法的,并且确实“遭受”了您提到的相同问题
    • @M.M. int&& 函数参数的一个主要区别是它们是明确的输入,并且引入 std::move 是为了确保调用代码明确承认它可能会令人惊讶和有问题的地方,而 int& 暗示某种输出方式并隐含地具有临时变量绑定更有可能是偶然完成的。
    【解决方案4】:

    int i = -1, &r = 0;基本相当于写

    int i = -1;
    int &r = 0
    

    第二个语句尝试将非const 左值绑定到0,这根本不是左值(0 不是可以获取地址的对象)。但是,当它是 const 左值时它会成功,因为它被绑定(虽然不是直接)到右值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 2018-03-04
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多