3
我做了一个程序来评估这样的性能差异:复制省略和移动语义不能按预期工作
func3(func2(func1()));
VS这样的:
retval1 = func1();
retval2 = func2(retval1);
func3(retval2);
我更喜欢后者的可读性和易用性的调试,我想知道编译器(MSVC 12.0)是否会优化发布版本中的中间对象。我的测试程序是这样的:
#include <iostream>
using namespace std;
struct Indicator {
Indicator() {cout << "Default constructor" << endl;}
Indicator(const Indicator& other) {cout << "Copy constructor" << endl;}
const Indicator& operator=(const Indicator& other) {cout << "Assignment operator" << endl;}
~Indicator() {cout << "Destructor" << endl;}
};
Indicator func1()
{return Indicator();}
Indicator func2(Indicator&& i)
{return std::move(i);}
Indicator func3(Indicator&& i)
{return std::move(i);}
int main() {
Indicator i = func3(func2(func1()));
cout << &i << endl;
return 0;
}
我很惊讶地看到,即使-02,还有正在创建的Indicator
三个实例:
Default constructor
Copy constructor
Copy constructor
Destructor
Destructor
00000000002EFC70
Destructor
Press <RETURN> to close this window...
与我的移动语义的理解这种矛盾,这就是说在这种情况下应该只创建一个Indicator
实例。我还认为编译器应该能够将NRVO用于链式函数调用。有人可以向我解释这里发生了什么事吗?
[(另见)(http://stackoverflow.com/questions/8283589) –
这是值得大家注意的Visual C++ 12不会产生隐性转移构造的。 – stgatilov
啊。好的我知道了。我刚刚习惯了遵守3的规则,现在我必须记得定义移动构造函数以及... – Carlton