簡體   English   中英

c ++移動構造函數,使用默認構造函數生成

[英]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;

http://ideone.com/u46GWS

在哪里說默認構造函數會導致移動構造函數的創建?

移動構造函數的創建與默認構造函數的存在或缺乏之間沒有關系。

從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM