我想知道NRVO是否在我正在进行的项目中处于活动状态(即Qt,使用MSVC 2013 64位)。
所以我写了一段代码:
class foo
{
public:
foo(){qDebug() << "foo::foo";}
foo(const foo& c){(void)c;qDebug() << "foo::foo( const foo& )\n";}
~foo(){qDebug() << "foo::~foo";}
};
foo bar()
{
foo local_foo;
return (local_foo);
}
void func()
{
foo f = bar();
}它给了我以下的输出:
foo::foo foo::~foo
我上面提到的链接期望的是:
foo::foo() foo::foo( const foo& ) foo::~foo() foo::~foo()
但当我把酒吧电话换成
foo f = foo(bar())然后我得到与链接相同的输出。
下面是我的问题:为什么"foo f= bar()“不调用复制构造函数?它是否调用了operator=,在调用之前,f是原始存储?(那么,为什么从2004年开始的链接就不一样了)?所以我必须得出结论,NRVO没有打开,对吗?
发布于 2016-02-29 14:16:07
为什么"foo f= bar()“不调用复制构造函数?
因为编译器允许埃利德复制。
它是否调用了operator=,在调用之前,f是原始存储?
不是的。
那么为什么2004年的链接不一样呢?
他们可能使用了另一个编译器、编译器的另一个版本或编译器的其他设置,而他们的编译器并没有删除该副本。
所以我必须得出结论,NRVO没有打开,对吗?
从第一个输入,您可以得出NRVO 是打开的结论。从第二个输出可以得出结论,有一个副本没有被删除。但是,由于打印的副本比没有NRVO的副本少,所以您可以得出结论,NRVO是打开的,但并不适用于所有副本。
那么,"foo f= bar()“和foo f=foo(bar())之间有什么区别呢?
第一个副本从f的返回值初始化bar()。
第二个构造器显式地使用复制构造函数构造一个临时对象,然后从该临时对象复制初始化f。这两份副本都可以删掉。
https://stackoverflow.com/questions/35701281
复制相似问题