c++ - 为什么标准不允许通过非常量引用传递临时变量?

标签 c++ pass-by-reference temporary

<分区>

我已经阅读了很多有关该标准如何不允许通过非常量引用传递临时变量的内容,但我可以找到任何令人信服的理由。

我遇到的通常争论是它是不安全的,因为值的生命周期是未知的。但实际上它不是,它绑定(bind)到函数,它是它的参数,并且将保持“事件”直到该函数返回,因此在该函数内部使用它是安全的,将它传递给它内部的另一个函数和另一个...基本上只要都是同步执行,就应该是安全的,因为对象会保留在那里,直到第一个接收它的函数返回。

这两种方法之间的根本区别是什么?

doSomething(createSomething());

{
    something s = createSomething();
    doSomething(s);
}

除了第二个使用对象标识符不必要地污染范围之外,您将只使用一次。

在我看来,它是临时的这一事实仅限制了造成损害的可能性,因为在该函数调用之后将不再使用它。

有人可以通过引用传递临时变量来提供在实践中可能发生什么样的坏事的片段吗?

另外,我的问题是严格的 c++11 之前的问题,所以右值引用超出了它的范围。

编辑:从链接的问题,sbi 的回答:

// this doesn't compile: 
g(getx()); // g() would modify an object without anyone being able to observe

但这意味着人们通过引用传递某些东西的唯一原因是能够观察该函数返回后所做的更改。现在,显然,如果您使用临时文件,不用说这不是您意图的一部分,刚才提到的原因也不是通过引用传递的唯一原因。这就是为什么该问题的范围与标记为重复的问题的范围不同。您很可能通过引用传递以避免代价高昂的复制,并且您的设计可能涉及使用完全封装在该函数中的对象以及在其中调用的函数。

另一个问题侧重于引用传递的一种用法,没有解释可能出错的地方,也没有考虑到使用临时否定与答案地址相关的事实。它基本上回答“因为它会在没有任何人能够观察到的情况下修改一个对象”,这是毫无意义的,但是当您首先使用临时对象时,这显然不是意图。

换句话说,答案是“你做不到,因为当你不想观察变化时,你无法观察到变化”...... DO'H 限制如何?是无法做您显然不想做的事情?

最佳答案

原因是 Stroustrup 先生推断传递对可变临时变量的引用很可能是编程错误的结果——因为在函数调用后无法访问临时变量中的任何计算结果。

例子:

struct foo {...};

func(foo());
// the foo has already been destroyed here, so any modified state is inaccessible.

公平地说,尽管自从 r 值引用的发展以来这看起来是短视的,但他的推理是合理的。虽然可能需要多写一行代码,但总有办法达到同样的效果。

例子:

{
  foo f;
  func(f);
}

foo_func();

哪里:

void foo_func() {
  foo f;
  func(f);
}

这里是对我所看到的示例的重新引用,该示例被引用为您无法在函数调用中将可变临时值绑定(bind)到左值的原因。这个错误很微妙,但很严重,很难发现:

void inc(int& arg) { arg++; }

typedef long MyInt;

int main() {
  MyInt i = 0;
  inc(i);  // <<-- HINT: implicit conversion from long to int creates a temporary COPY, not reference
  if (i == 1) {
     // Life-saving logic
  }
}

来源:comp.lang.c++.moderated

关于c++ - 为什么标准不允许通过非常量引用传递临时变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27464464/

相关文章:

c++ - DrawInstanced 与 DrawIndexed 并将它们混合在一起

c++ - 使用带直接 x 的点 Sprite 。需要采取什么步骤?

c++ - 速度和动量 - 我无法走远

passwords - mysqld.log 中没有临时密码

c++ - 临时对象存储在哪里?

c++ - 使用 OpenGL 在拖动鼠标上绘制不连续的线

c++ - 将仅移动函数参数传递给boost::thread构造函数

c++ - 在 C++ 中通过引用传递的两种方式?

java - 为什么 Java 中不能通过引用调整数组大小?

c++ - 为什么占用临时地址是非法的?