我花了几个小时讨论rvalue s和lvalue。以下是我所理解的
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)。
是那么回事吗?如果没有,请详细说明。
发布于 2012-12-06 22:40:53
rvalues和lvalue的概念并没有从旧的C++转变为C++11,您所描述的"C++03“就是应该发生的事情。在某些情况下,一些编译器优化可以减少不必要的副本数量(包括不必要的复制构造函数调用!),但在其他情况下是一样的。
改变的是C++11引入了rvalue-reference (T&&)的概念。
有几篇文章可以在上面搜索,例如在这里:
01.html
发布于 2012-12-06 22:40:33
他们不一样。按照这两种标准,Bar2()都是UB。不能返回通过引用在堆栈上创建的对象。
在C++03中,Bar1()可能利用RVO,不会复制任何内容。在C++11中,Bar1()甚至会使用RVO,或者如果RVO不可能使用移动构造函数。
发布于 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,则大多数编译器将省略额外对象的构造。https://stackoverflow.com/questions/13753872
复制相似问题