首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回值( c++03 vs 11 )

返回值( c++03 vs 11 )
EN

Stack Overflow用户
提问于 2012-12-06 22:36:23
回答 5查看 208关注 0票数 0

我花了几个小时讨论rvalue s和lvalue。以下是我所理解的

代码语言:javascript
复制
int main()
{
  //.....
  Foo foo = Bar1();
  foo = Bar2();
  //......
}  

Foo Bar1()
{
  //Do something including create foo
  return foo;
}

Foo& Bar2()
{
  //Do something including create foo
  return foo;
}

在c++03下,Bar1()将复制返回对象(就在返回之前),然后返回复制对象的地址;执行将要销毁的对象的浪费副本。Bar2()将返回在函数中创建的对象。

在c++11下,Bar1()Bar2()本质上是等价的(也相当于Bar2() of c++03)。

是那么回事吗?如果没有,请详细说明。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-12-06 22:40:53

rvalues和lvalue的概念并没有从旧的C++转变为C++11,您所描述的"C++03“就是应该发生的事情。在某些情况下,一些编译器优化可以减少不必要的副本数量(包括不必要的复制构造函数调用!),但在其他情况下是一样的。

改变的是C++11引入了rvalue-reference (T&&)的概念。

有几篇文章可以在上面搜索,例如在这里:

01.html

票数 1
EN

Stack Overflow用户

发布于 2012-12-06 22:40:33

他们不一样。按照这两种标准,Bar2()都是UB。不能返回通过引用在堆栈上创建的对象。

在C++03中,Bar1()可能利用RVO,不会复制任何内容。在C++11中,Bar1()甚至会使用RVO,或者如果RVO不可能使用移动构造函数。

票数 6
EN

Stack Overflow用户

发布于 2012-12-06 22:50:26

Bar2()没有在C++ 2003或C++ 2011中创建任何副本。对于Bar1()foo的副本是在C++ 2003和C++ 2011中创建的。rvalue引用的使用仅在您确实有rvalue或当您有一个即将消失的lvalue并且它正在被返回时才适用。

当然,这个示例碰巧是未定义的行为,因为正在返回的foo是正在初始化的foo。也就是说,似乎您的示例由于没有说明返回时foo的含义而搞砸了。假设每个函数都有一个局部变量foo,那么根据这两种标准,Bar2()都是未定义的行为,并且Bar1()有一些不同:

  • 如果有Foo的移动构造函数,C++ 2011可以使用移动构造函数,而C++ 2003可以使用复制构造函数。
  • 是否使用移动构造函数或复制构造函数取决于函数的其余部分和编译器:如果Bar1()中的所有Bar1()语句返回foo,则大多数编译器将省略额外对象的构造。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13753872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档