[英]c++ move constructor generated with default constructor
看看這個問題,它只提到了C ++ 11及更高版本 :
如果沒有用戶聲明的復制構造函數,復制賦值運算符或析構函數,並且生成的移動構造函數有效(例如,如果它不需要分配常量成員),則自動生成移動構造函數(§12.8/ 10) 。
所以,如果我有以下代碼:
class Y
{
public:
Y(const Y&) {}
};
struct hasY {
hasY() = default;
hasY(hasY&&) = default;
Y mem;
};
hasY hy, hy2 = std::move(hy); //this line fails as expected as Y has a user-defined copy constructor.
現在,如果我將默認構造函數添加到Y:
Y() {}
錯誤消失了。
在哪里說默認構造函數會導致移動構造函數的創建?
(使用VS 2015更新2)
class Y
{
public:
Y(const Y&) {}
};
這個類沒有默認的構造函數,所以
struct hasY {
hasY() = default;
hasY(hasY&&) = default;
Y mem; // << requires default ctor
};
你得到的錯誤與移動構造函數無關:
prog.cpp: In function 'int main()':
prog.cpp:13:7: error: use of deleted function 'hasY::hasY()'
hasY hy;
^
prog.cpp:8:5: note: 'hasY::hasY()' is implicitly deleted because the default definition would be ill-formed:
hasY() = default;
在哪里說默認構造函數會導致移動構造函數的創建?
移動構造函數的創建與默認構造函數的存在或缺乏之間沒有關系。
從C ++ 11標准:
12.8復制和移動類對象
...
9如果類X的定義沒有顯式聲明一個移動構造函數,那么當且僅當一個移動構造函數被隱式聲明為默認值時
- X沒有用戶聲明的復制構造函數,
- X沒有用戶聲明的復制賦值運算符,
- X沒有用戶聲明的移動賦值運算符,
- X沒有用戶聲明的析構函數,和
- 移動構造函數不會被隱式定義為已刪除。
它與移動構造函數無關。它與默認構造函數有關。 嘗試這個:
class Y
{
public:
Y(const Y&) {}
};
struct hasY {
hasY() = default;
hasY(hasY&&) = default;
Y mem;
};
hasY hy; // This will cause an error because there is no default constructor
現在,如果添加默認構造函數: Y(){}
,錯誤將消失。
正如@MM評論的那樣,在這種情況下將調用復制構造函數。
您可以嘗試以下代碼:
class Y{
public:
Y(){std::cout << "Default constructor\n";}
Y(const Y&) {std::cout << "Copy constructor\n";}
};
struct hasY {
hasY() = default;
hasY(hasY&&) = default;
Y mem;
};
int main(){
hasY hy;
hasY h=std::move(hy);
}
它將打印:
默認構造函數
復制構造函數
如果你想使類不可移動,你應該自己刪除移動構造函數Y(Y&&)=delete;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.