繁体   English   中英

c ++ rvalue传递给const引用

[英]c++ rvalue passed to a const reference

我试图理解关于引用和rvalues的确切C ++(前C ++ 0x)行为。 以下是否有效?

void someFunc ( const MyType & val ) { 
    //do a lot of stuff
    doSthWithValue ( val);
} 

MyType creatorFunc ( ) { 
    return MyType ( "some initialization value" ); 
} 

int main () { 
    someFunc ( creatorFunc() ); 
    return 0; 
}

我在我试图修改的库中找到了类似的代码。 我发现Visual Studio 2005下的代码崩溃了。
我理解上述方式,发生的事情是:
creatorFunc按值返回,因此创建了一个临时的MyType对象obj1。 (并保持...在堆栈上?)someFunc正在引用该临时对象,随着计算的进行,临时对象被覆盖/释放。
现在,令人难以置信的是代码最常使用。 更重要的是,只需一段简单的代码就无法重现崩溃。
这里发生了什么/应该发生什么? 如果引用(val)是const,那有关系吗? 从creatorFunc返回的对象的生命周期是多少?

返回值具有临时的生命周期。 在C ++中,这意味着创建该类型的完整表达式,因此在调用someFunc返回之前,不应调用MyType的析构函数。

我很好奇你的'被覆盖/被释放'。 当然在这个对象上调用delete是不行的; 它存在于堆栈中并删除它可能会导致堆损坏。 此外,覆盖/修改它也可能是坏事。 您的示例使用常量“C字符串”; 在许多编译器上,这样的值存储在只读内存中,因此稍后尝试修改它可能会导致崩溃/访问冲突。 (但我不确定Visual C ++是否进行了这种优化)。

传递临时const与可变引用之间存在很大差异。 标准C ++不允许创建对临时文件的可变引用,并且大多数编译器(包括GCC)都会拒绝它,尽管至少某些版本的Visual C ++允许它。

如果您使用可变引用传递它,您要写的是:

   MyType t = creatorFunc();
   someFunc(t);

creatorFunc()创建的临时生命周期一直持续到someFunc调用结束。 实际上,下一个序列点(松散地,分号)。

someFunc正在引用该临时对象,随着计算的进行,临时对象被覆盖/释放“

听起来someFunc正在做“坏事”。 您不应该覆盖或释放由const&传递的对象。

通常,临时对象(例如函数调用返回的对象)的生命周期延伸到“封闭表达式”的末尾。 但是,对引用的临时绑定通常会将其生命周期“提升”到引用的生命周期。

因此传递给someFunc()的临时值应该保持活动状态并且可以访问,直到someFunc()返回为止。 但是,如果someFunc() (或其可能调用的任何内容,例如doSthWithValue() )将指针或对val引用存储起来,例如在集合或其他对象中,以供稍后使用,则临时对象将不会更长的活着,你可能会崩溃尝试使用它。 这可能就是为什么你看到简单的代码没有崩溃,引用一个临时的,而更复杂的代码崩溃。

有关详细信息,请参阅以下项目:

函数的返回值(不是引用),绑定到调用函数中的const引用; 它的生命周期如何扩展到调用函数的范围? C ++常量引用生命周期(容器适配器)

另请注意,该标准允许temporaries仅绑定到const引用,但正如Jack Lloyd提到的某些版本的MSVC(根据http://msdn.microsoft.com/en-us/library/cfbk5ddc.aspx的 VS 2003之前) )允许您将它们绑定到非const引用。 但是,在快速测试中,我发现VS 2010的编译器仍然允许temporaries绑定到非const引用。

您只能将临时绑定到const引用。

是的,重要的是引用是const。 您不能将临时绑定到非const引用,因此代码不会编译。

除此之外,您的代码定义明确,并将按预期工作。

我有同样的问题,当我在SO上发表评论时,因为之前提到它而受到重创。 我觉得别人有这个问题!

我还在使用VS 2005(SP1),也许是一些编译器优化错误?

从结果creatorFunc()似乎并不仍然活着,呼叫someFunc ( creatorFunc() ); 我发现要做的唯一事情是将其拆分为2行,从而删除临时变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM