为什么标准不允许通过非const引用传递临时值?

时间:2014-12-13 22:50:04

标签: c++ pass-by-reference temporary

我已经阅读了很多关于标准如何不允许临时文件通过非const引用,但我可以找到任何有说服力的原因。

我遇到的常见理由是它不安全,因为值的生命周期是未知的。但实际上并非如此,它与功能有关,它的参数是什么,并且将保持"活着"直到该函数返回,所以在该函数内使用它是安全的,将它传递给它内部的另一个函数和另一个...基本上只要它是所有同步执行,它应该是安全的,因为该对象将保持在那里直到接收它的第一个函数返回。

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

doSomething(createSomething());

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

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

我看到它的方式,它是一个临时的事实只会限制造成伤害的可能性,因为在该函数调用之后它将不再被使用。

有人可以通过引用临时传递来提供实际可能发生的坏事吗?

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

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

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

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

另一个问题集中在使用传递参考,并没有解释可能出现的问题,也没有考虑到使用临时否定答案解决的问题。它基本上回答了"因为它会修改一个对象而没有任何人能够观察到#34;这被正确地呈现为毫无意义,但是当你在第一时间使用临时时,这绝对不是意图。

换句话说,答案是"你不能这样做,因为当你不想观察变化时你无法观察到这些变化&#34 ; ... DO' H限制是如何无法做一些你显然不想做的事情?

1 个答案:

答案 0 :(得分:0)

原因是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);
}

这里是我所看到的示例的重新引用,因为您无法将可变临时值绑定到函数调用中的l值。这个错误是微妙的,但很严重,很难找到:

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