在VS2010中运行此代码时,未应用NRVO。
#include <stdio.h>
class A
{
public:
A() { printf( "I am in constructor\n" ); }
A(const A& a) { printf( "I am in copy constructor\n" ); }
~A() { printf( "I am in destructor\n" ); }
int i;
};
A f(int j)
{
A a;
if ( j ) return a;
a.i = j;
return a;
}
int main()
{
A a;
a = f(5);
}
编辑:这与析构函数有关。当我评论它的线时,使用NRVO。但为什么会这样呢?
答案 0 :(得分:4)
为什么不在这里应用NRVO?
如果这纯粹是对你的好奇,并且你想知道VC10如何在算法上决定是否执行NRVO,那么唯一能够可靠地回答这个问题的人就是那些知道VC10如何在内部工作的人 - 那些写它的人
根据C ++ 11标准,根据C ++ 11标准,编译器允许在这种情况下执行NRVO,而不这样做只是编译器的决定 - 不是由于任何有效性约束。根据第12.8 / 31段:
[...]在下列情况下允许复制/移动操作(称为复制省略) 可以合并以消除多个副本):
- 在具有类返回类型的函数的返回语句中,当表达式是a的名称时 具有相同cv-unqualified的非易失性自动对象(函数或catch子句参数除外) 键入函数返回类型,可以通过构造省略复制/移动操作 自动对象直接进入函数的返回值
[...]
但是,如果您要求强制您的编译器执行NRVO,那么答案是“您不能”。
完全由编制者自行决定是否申请NRVO。你不能指望它,你不能指望它不被执行。据我所知,这是所谓“ as-if ”规则的唯一例外。
这就是说,当你提高优化水平时,获得NRVO的可能性会增加。
答案 1 :(得分:0)
我不知道您在您的环境中看到了什么,但这在GCC中正常运行(例如see here):
<强>正常:强>
I am in constructor
I am in constructor
I am in destructor
I am in destructor
使用-fno-elide-constructors
:
I am in constructor
I am in constructor
I am in copy constructor
I am in destructor
I am in destructor
I am in destructor