我用下面的代碼測試複製省略:爲什麼copy elision不能使用std :: move?
class foo
{
public:
foo() {cout<<"ctor"<<endl;};
foo(const foo &rhs) {cout<<"copy ctor"<<endl;}
};
int g(foo a)
{
return 0;
}
int main()
{
foo a;
g(std::move(a));
return 0;
}
我預計只有默認的構造函數被調用,因爲g()
參數是一個右值和副本將被省略。但結果顯示默認構造函數和複製構造函數都被調用。爲什麼?
如果我將函數調用更改爲g(foo())
,副本將被忽略。 foo()
和std::move(a)
的退貨類型有什麼區別?我怎樣才能使編譯器elide副本左值?
你不能。'g'按值取其參數,所以編譯器必須確保傳遞的對象不同於從調用範圍可訪問的任何對象。如果傳遞的對象是左值,則不會暫時消除並且不能消除副本。 – 2012-08-14 06:07:11
你期望有多少析構函數調用? ;) – curiousguy 2012-08-14 06:29:42
您可能需要[read up](http://stackoverflow.com/a/11540204/252000)瞭解'std :: move'實際執行的操作。 – fredoverflow 2012-08-14 11:25:23