【问题标题】:What's the behavior of modifying rvalues through lvalue reference?通过左值引用修改右值的行为是什么?
【发布时间】:2014-11-11 21:33:54
【问题描述】:

假设我有以下:

class foo
{
public:
    foo& Ref() { return *this; }

    int stuff;
};

void do_stuff(foo& f)
{
    f.stuff = 1;
}

int main()
{
    do_stuff(foo().Ref());
}

我正在通过左值引用修改右值。这合法吗?如果是或不是,有人可以解释原因并在标准中提供相关部分吗?

【问题讨论】:

  • 由于您在临时不存在后使用对临时的引用,因此行为未定义。
  • 我已经更新了我的示例,希望能解决生命周期问题。终生问题不是故意的。

标签: c++


【解决方案1】:

我正在通过左值引用修改右值。

不,你不是。在do_stuff 内部,表达式f 是左值,而不是右值。 值类别是关于表达式,而不是对象;对象有类型

您正在修改一个临时的,但 that's fine。我不能引用任何简单的段落来说明这一点;根本不禁止在任何地方修改碰巧是临时的对象。

【讨论】:

  • 临时是一个右值。我没有修改引用本身。
  • @void.pointer:不,不是。没有“这个对象是一个左值”、“这个对象是一个右值”这样的东西。这不是价值类别的工作方式。值类别是 表达式 的属性,例如表达式 f 恰好命名了您已声明的对象(因此,在本例中,它是 lvalue 表达式)。
  • 是的,它是???请解释而不是说“不,不是”。当我真正使用 f 时,是的,它是一个左值,但我正在考虑这个问题的起源(内存所在的位置)。无论如何,这似乎分散了我最终想要问的内容。
  • @void.pointer:我觉得你一直在读我大约 5% 的话。请再次检查我的答案和 cmets。这不是“分心”;这是您问题的答案,由于给出的原因,这从根本上是有缺陷的。
  • @void.pointer 也许这会澄清一些事情:临时对象不允许直接绑定到非常量引用,但这是为了防止程序员错误,而不是因为临时是不可变的。临时对象保证存在直到它出现的 full-expression 结束,因此在 full-expression 期间对该对象的引用是有效的。
猜你喜欢
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 2015-02-06
  • 1970-01-01
  • 2018-01-13
相关资源
最近更新 更多