[英]Why do not C++11's move constructor/assignment operator act as expected
#include <iostream>
using namespace std;
struct A
{
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
A(A&&)
{
cout << "A(A&&)" << endl;
}
A& operator =(A&&)
{
cout << "A& operator =(A&&)" << endl;
return *this;
}
};
struct B
{
// According to the C++11, the move ctor/assignment operator
// should be implicitly declared and defined. The move ctor
// /assignment operator should implicitly call class A's move
// ctor/assignment operator to move member a.
A a;
};
B f()
{
B b;
// The compiler knows b is a temporary object, so implicitly
// defined move ctor/assignment operator of class B should be
// called here. Which will cause A's move ctor is called.
return b;
}
int main()
{
f();
return 0;
}
我的預期輸出應為:
A()
A(A&&)
~A()
~A()
但是,實際輸出為:(C ++編譯器為:Visual Studio 2012)
A()
~A()
~A()
這是VC ++的錯誤嗎? 還是只是我的誤會?
Visual C ++ 2012未實現右值引用和移動操作的最終C ++ 11規范(該規范在標准化過程中多次更改)。 您可以在Visual C ++ Team Blog帖子“ Visual C ++ 11中的C ++ 11功能”的 rvalue引用下找到更多信息。
具體來說,在您的示例中,這以兩種方式體現出來:
A
用戶定義的移動操作的定義不會取消隱式聲明的復制操作。
B
沒有隱式定義的移動操作。
我認為移動構造函數的聲明不會阻止復制ctor的生成。 ...而且似乎編譯器比copy構造函數更喜歡copy構造函數。
實際上,根據12.8 [class.copy]第7段,移動構造函數的存在應防止復制構造函數:
如果類定義未明確聲明一個副本構造函數,則將隱式聲明一個副本構造函數。 如果類定義聲明了move構造函數或move賦值運算符,則隱式聲明的copy構造函數將定義為delete; 否則,將其定義為默認值(8.4)。
但是,移動構造的細節一直更改到過程后期,並且VC ++似乎並沒有實現實際的標准,而是實現了較早的修訂。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.