【问题标题】:Is it legal to take the address of a const lvalue reference?获取 const 左值引用的地址是否合法?
【发布时间】:2012-11-08 00:05:55
【问题描述】:
#include <iostream>
int foo()
{
  return 0;
}

int main()
{
  const int& a = foo();
  std::cout << &a << std::endl;
}

在这段代码中,a 绑定到一个右值。获取地址是否合法? (我所说的合法​​是指:代码格式不正确?我是否导致了未定义的行为?)

【问题讨论】:

  • 我会说没关系,因为临时对象的生命周期与它所绑定的 const 引用一样长,所以打印它的地址应该没问题。不过,我还不能引用它。
  • @chris: 值在寄存器而不是堆栈中返回的情况呢?
  • 对我来说,它看起来像是具有已定义行为的格式良好的代码。 “引用绑定到的临时对象或引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在……”换句话说,此时值很漂亮就像任何其他本地人一样。
  • @qdii,我想过,但是当您获取地址时,我想它必须被卡在内存中。当您考虑它时,编译器可以将它想要的任何变量放在寄存器中,而不是将它们保存在内存中。因此,这相当于在这方面获取任何其他变量的地址。
  • @qdii:这是一个与您无关的实现细节。编译器需要尽一切努力使代码工作,如果这意味着不使用寄存器,那就这样吧。

标签: c++ lvalue rvalue


【解决方案1】:

这很好。在 C++11 中,您甚至可以这样做:

int&& a = foo();
a = 123;

您可以考虑这样的临时工(从概念上和总体上):

x = func(); // translated as:

auto __temporary = func();
x = __temporary;
__destruct_value_now_and_not_later(__temporary);

除非x 是引用类型的定义,否则编译器会注意到您有意引用临时值并通过删除早期销毁代码来延长其生命周期,使其成为普通变量。

【讨论】:

  • 我相信,只有引用 const 值才能延长生命周期。
  • @GManNickG :嗯,不是 any 引用(例如非常量左值引用),但它适用于 &amp;&amp;
  • 这将如何实现,被调用者在堆栈上为变量分配空间,但不会根据调用者将结果分配给什么来释放它?
  • @SethCarnegie:抱歉,我不关注。请注意,这只是有目的地省略细节的概括;它的实际实施方式不会影响这个想法。通常,调用者负责为返回值提供空间(假设它不适合寄存器,调用者和被调用者都事先知道)。
  • @GManNickG 哦,你是对的,我在想一些无关紧要的事情。你知道这是在标准的哪个部分(临时工寿命的延长)吗?
【解决方案2】:

是的。在变量a 超出范围之前,它捕获的临时变量是有效的。 Herb Sutter can explain it better.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多