[英]Why does deleting the move constructor cause a compile error?
以下代碼可以正常工作:
#include <iostream>
using namespace std;
struct oops
{
~oops()
{
cout << " oops! " << endl;
}
};
struct sample
{
oops* x = nullptr;
sample(oops* p) : x(p)
{
cout << "sample: " << p << endl;
}
~sample()
{
delete x;
cout << "destroy sample " << endl;
}
sample(const sample&)
{
cout << "copy sample " << endl;
}
sample(sample&&)
{
cout << "move sample " << endl;
}
};
int main()
{
sample s = new oops;
return 0;
}
結果:
sample: 0x1470c20
oops!
destroy sample
它清楚地表明,移動和復制構造函數都沒有被調用。 刪除這些構造函數時
sample(const sample&) = delete;
sample(sample&&) = delete;
gcc給出了編譯錯誤:
bpp.cpp: In function ‘int main()’:
bpp.cpp:29:17: error: use of deleted function ‘sample::sample(sample&&)’
sample s = new oops;
^
bpp.cpp:24:2: note: declared here
sample(sample&&) = delete;
^
bpp.cpp:14:2: note: after user-defined conversion: sample::sample(oops*)
sample(oops* p) : x(p)
^
這與-fno-elide-constructors
有什么關系嗎? 如何在不定義這些構造函數或使用顯式構造函數的情況下編譯它?
編輯:我的GCC版權是5.4.0。 命令是:
g++ bpp.cpp -std=c++17
sample s = new oops;
這是一種復制初始化的形式。 對於編譯器來解決它直到C ++ 17,必須存在復制或移動構造函數。 但是,由於優化(使用GCC和-fno-elide-constructors
,調用移動構造函數),編譯器可以自由地調用它的調用。
從C ++ 17開始,這些構造函數都不是必需的: https : //wandbox.org/permlink/3V8glnpqF5QxljJl 。
如何在不定義這些構造函數或使用顯式構造函數的情況下編譯它?
非常簡單,避免復制初始化並使用直接初始化 :
sample s { new oops };
或者,使用C ++ 17。
這行代碼:
sample s = new oops;
相當於寫作:
sample s = sample(new oops);
在C ++ 11和C ++ 14中,這隱式調用移動構造函數(或復制構造函數,如果沒有移動構造函數可用)。 因為允許編譯器省略副本和移動,所以實際移動被省略,並且在調用移動構造函數時它不會顯示任何內容。 即使實際移動被省略,也不允許程序隱含地引用已刪除的函數,因此存在編譯器錯誤。
您可以通過將初始化更改為任一來解決此問題
sample s { new oops };
要么
sample s ( new oops );
或者,如果你真的想使用=
,你可以利用臨時的生命周期擴展來寫
// s won't get destroyed until the end of the scope
// it's safe to use s after this statement
sample&& s = new oops;
C ++ 17對對象所屬的值類別集進行了一些更改。在C ++ 17中, sample(new oops)
成為prvalue,而c ++ 17標准要求編譯器必須將prvalues放入到位復制或移動它們。 這是通過黑暗魔法和巫術的結合來完成的。
這意味着sample s = new oops;
在c ++ 17中是合法的 。
-std=c++17
時仍然無法編譯? 這段代碼應該在C ++ 17下編譯 ,並且你得到的錯誤是因為gcc 6.3和更早版本沒有實現c ++ 17標准的那部分。 此問題已在gcc 7.1中修復,代碼將按預期編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.