【问题标题】:Is it safe to bind an unsigned int to a signed int reference?将 unsigned int 绑定到 signed int 引用是否安全?
【发布时间】:2022-01-14 15:20:15
【问题描述】:

在同事的代码中遇到类似内容后,我无法理解为什么/如何在没有编译器警告或错误的情况下执行此代码。

#include <iostream>

int main (void)
{
    unsigned int u = 42;

    const int& s = u;

    std::cout << "u=" << u << " s=" << s << "\n";

    u = 6 * 9;

    std::cout << "u=" << u << " s=" << s << "\n";
}

输出:

u=42 s=42
u=54 s=42

首先,当我像这样混合有符号/无符号整数时,我希望编译器会发出某种诊断。如果我尝试与&lt; 进行比较,它当然可以。这是让我感到困惑的一件事。

其次,我不确定第二行输出是如何生成的。我预计s 的值为54。这是如何工作的?编译器是否创建了一个匿名的、自动签名的整数变量,分配了u 的值,并将引用s 指向该值?还是在做其他事情,比如将 s 从对普通整数变量的引用更改?

【问题讨论】:

  • const int&amp; s = u; 首先创建一个新的临时int,然后将其分配给const int&amp;。这就是为什么它不适用于非常量引用
  • 这是一个我从未见过的有趣的 C++ 陷阱。
  • 这可能有助于理解行为,以了解在 C++ 中 const 引用可以在某些情况下延长分配给它的临时对象的生命周期。基本上,如果临时对象是在引用初始化期间创建的,在大多数情况下,它会将临​​时对象的生命周期延长到引用的生命周期。函数局部变量就是其中一种情况。
  • 请参阅here 了解有关延长寿命的更多信息。 “可以通过绑定到 const 左值引用 [或右值引用 (C++11 起)] 来延长临时对象的生命周期,有关详细信息,请参阅引用初始化。”
  • @Eljay:这种特殊情况不是 UB:eel.is/c++draft/basic.lval#11.2

标签: c++ reference


【解决方案1】:

引用不能直接绑定到不同类型的对象。给定const int&amp; s = u;u首先隐式转换为int,这是一个临时的、全新的对象,然后s绑定到临时的int。 (对const 的左值引用(和右值引用)可以绑定到临时对象。)临时对象的生命周期延长到s 的生命周期,即退出main 时将被销毁。

【讨论】:

  • 感谢您的解释。这对我来说完全违反直觉。难怪人们为什么害怕 C++!
  • 有趣的东西,这意味着printf("%p %p", &amp;u, &amp;s); 将打印不同的值,因为这两个变量存储在堆栈中的不同位置。
  • @russoue 如果您遵循 C++ 规则,那么您会发现它变得直观。我非常沉迷于这些 C++ 的东西。 :)
猜你喜欢
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 2019-09-08
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
相关资源
最近更新 更多