为什么非const引用临时对象?

时间:2012-12-11 19:13:08

标签: c++ temporary-objects

C ++只允许将临时对象分配给const引用。它不允许分配临时对象来引用。

例如:

String& a = String("test");         // Error
const String& a = String("test");   // Ok

到处都是谷歌搜索这个结果,我只看到以下答案

  1. 修改临时对象会导致无法识别的问题
  2. 修改临时对象很危险
  3. 在某些时候,你会忘记它是一个临时变量
  4. 有人说,临时对象在声明后消失了。所以你不应该修改它。

    如果C ++非常热衷于阻止修改临时对象,它应该阻止读取临时对象吗?如果临时对象消失了,那么从那里读取内容是没有意义的吗?可能发生权利的可能情况也可能涉及阅读。

    那为什么它一直阻止写入并允许读取?

    请给我一个可靠的c ++代码说明。

    请不要通过指出一些替代方案来偏离问题。请给我一个坚实的答案,代码为什么const int&允许和int&不允许用于临时对象。

    有人说&&在那里..我的问题不同.. 另一方面,改变不会反映出来。改变也不会反映即使它是const int&太。例如:双倍; Const int&我= a;一个++;不会影响我..

4 个答案:

答案 0 :(得分:28)

不允许引用临时值的原始案例是函数参数。假设这是允许的:

void inc(double& x)
{ x += 0.1; }

int i = 0;
inc(i);

为什么i没有改变?

答案 1 :(得分:10)

  

如果C ++非常热衷于阻止修改临时对象,它应该阻止读取临时对象吗?如果临时对象消失了,那么从那里读取内容是没有意义的吗?

不,阅读这个对象是非常明智的。仅仅因为它将来会消失并不意味着读取数据现在毫无意义。

open_file(std::string("foo.txt"));

std::string("foo.txt")是一个临时的,它会在调用open_file()后停止存在,但它确实存在的数据非常重要。

不允许temporaries绑定到非const引用的理性实际上并不是写入临时文本的一些基本问题。事实上,在许多地方,C ++非常乐意允许修改临时版:

std::string("foo") = "bar";

只是设计师认为它会导致足够数量的问题(可能是由于“输出参数”的常用习惯用法)而没有启用任何类似价值的东西,所以他们只是做出一个设计决定来禁止临时绑定到非常量引用。

现在使用右值参考,你可以完全按照以前禁止的那样做:

void foo(int &&output) {
    output = 1;
}

foo(2);

这很好用,它不是很有用。

答案 2 :(得分:3)

如果您有一个复制成本非常高的临时对象,您可能更愿意将const&带到该对象(比如函数返回),而不是将其复制到另一个变量中以便稍后使用。持续引用临时文件会延长临时文件的生命周期,只要参考文件存在,就可以访问任何可读状态。

不允许写入,因为只要你想改变一个变量,你就可以拥有一个真实的实例而不是一个仅作为非const引用别名的临时实例。

答案 3 :(得分:1)

这是有道理的。想想,在这一行中你真正想要的是什么:

String& a = String("test");         // Error

你想要一个参考。引用涉及它引用的对象。就像对象的地址一样(虽然引用不是地址,但这样解释更清晰)。你实际上试图获得类似地址String("test")的东西。但是这个对象会在下一行消失,所以如果它指向的对象不存在,它的地址是什么呢? a现在指向一些毫无意义的东西......

关于你的第二个问题,完全允许临时对象有什么意义,好吧,这没有什么不妥。例如,考虑要将String对象传递给函数的情况,该函数返回一个与该String对应的修改后的字符串。我们调用函数DoubleString,而不是做

String s("hello ");
String s2 = DoubleString(s);

您可以使用更简单,更方便的表格

String s2 = DoubleString(String("hello "));

请参阅,临时对象String("hello ")在整行代码中存活,这意味着它在发送到DoubleString之后及之后完好无损。它只在整行完成后销毁。