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