通过引用返回一个临时对象 [英] Is returning a temp-object by reference possible

查看:164
本文介绍了通过引用返回一个临时对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以从这个示例代码中的函数返回引用:

is it possible to return a reference from a function like in this example code:

string &erase_whitespace(string &text)
{
    text.erase(**etc.**);
    return text;
}

调用:

string text = erase_whitespace(string("this is a test"));
cout << test;

此代码是否有效?在Visual C ++它不会崩溃,但它看起来不对。

Does this code work? On Visual C++ it does not crash but it looks wrong.

感谢

推荐答案

根据C ++ 2003标准(草案)的第12.2.3节

From § 12.2.3 of the C++ 2003 standard (draft)


临时对象被销毁,

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.

§12.2.4:


有两个上下文,其中临时表在与完整
表达式的结束不同的点被销毁。 ...

There are two contexts in which temporaries are destroyed at a different point than the end of the full- expression. ...

§12.2.5:


第二个上下文是当引用绑定到临时时。引用为
bound的临时变量或临时变量所绑定的子对象的完整对象的临时变量在引用的生存期内仍然存在
,除非另有规定。 ...在函数调用(5.2.2)中临时绑定到引用
参数,直到完成包含调用的完整表达式。

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. ... A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.

§8.5.3.5是什么决定引用何时必须是一个const类型。如果临时是具有返回适当引用(这是一个口令)的转换运算符的类的实例,则可能将临时绑定到非const引用。示例可能更容易理解:

§8.5.3.5 is what determines when the reference must be a const type. It is possible for a temporary to be bound to a non-const reference if the temporary is an instance of a class that has a conversion operator that returns an appropriate reference (that's a mouthful). An example might be easier to understand:

class Foo {
    ...
    operator Bar&() const;
...
void baz(Bar &b);
...
    baz(Foo()); // valid
    baz(Bar()); // not valid

最后一行由于第12.3.2.1节的规定而无效,转换函数永远不会用于将[...]对象转换为[...]相同的对象类型(或引用
it)。您可以使用通过Bar的祖先和一个虚拟转换函数进行转换来使其工作。

The last line isn't valid because of § 12.3.2.1, which states "A conversion function is never used to convert [an ...] object to the [...] same object type (or a reference to it)". You might be able to make it work using casting via an ancestor of Bar and a virtual conversion function.

赋值是一个表达式(第5.17节),因此,在你的代码中的表达式(第1.9.12节)是赋值。这给出以下序列(暂时忽略临时字符串可能不能绑定到非const引用):

An assignment is an expression (§ 5.17), thus the full-expression (§ 1.9.12) in your code is the assignment. This gives the following sequence (forgetting for the moment that a temporary string probably can't be bound to a non-const reference):


  1. 创建一个临时字符串

  2. 临时字符串绑定到 string& text erase_whitespace 的参数

  3. erase_whitespace

  4. erase_whitespace 返回对临时
  5. 的引用
  6. string text

  7. 该临时项已销毁。

  1. A temporary string is created
  2. The temporary is bound to the string& text argument of erase_whitespace
  3. erase_whitespace does its thang.
  4. erase_whitespace returns a reference to the temporary
  5. The temporary is copied to string text
  6. The temporary is destroyed.


$ b b

在这种情况下,所有的都是kosher。正如Mike Seymour指出的,问题情况是将 erase_whitespace 的结果分配给引用。请注意,这可能不会引起直接的问题,因为存储字符串的区域可能包含与临时文件被销毁前相同的数据。下一次在堆栈或堆上分配的东西,... ...

So all is kosher in this case. The problem case, as Mike Seymour points out, would be assigning the result of erase_whitespace to a reference. Note that this likely wouldn't cause an immediate problem, as the area that stored the string probably contains the same data it did before the temporary was destroyed. The next time something is allocated on the stack or heap, however...

这篇关于通过引用返回一个临时对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆