[英]Why does clang complain about a deleted move ctor when I don't move anything?
前提 :
#include <iostream>
using namespace std;
class ABC {
public:
ABC() {
cout << "Default constructor ..\n";
}
ABC(const ABC& a) {
cout << "In copy constrcutor ..\n";
}
ABC(ABC&& aa) = delete;
};
int main(int argc, char* argv[]) {
ABC b{ABC{}};
return 0;
}
用GCC vs Clang編譯它
Clang - Apple LLVM version 8.1.0 (clang-802.0.42)
Gcc - 5.4.0 ubuntu
觀察 Clang抱怨刪除了Move構造函數。
Gcc完全不抱怨。 並將正確輸出。
問題為什么?
對於gcc,我知道如果你只是初始化lvalue和rvalue,它會優化並且實際上不會調用復制構造函數並將臨時值復制到左值。
為什么Clang有所不同? 我認為(不確定,因此問題)這是在C ++標准中,哪一個偏離(或不)? 或者我做錯了什么。
編譯命令 : g++ --std=c++11 -O3 file.cpp
為了更多的樂趣,刪除花括號,並添加括號;)
ABC b{ABC{}};
到, ABC b(ABC());
,與這個問題無關。
編輯 :有人將問題標記為重復,但事實並非如此。 我明確表示我認為C ++ 11標准包括復制省略。 但是,CLANG似乎對構造函數的關鍵性沒有相同的行為。
這里是鏈接: http : //en.cppreference.com/w/cpp/language/copy_elision
很明顯 ,它說的是C ++ 11。 我相信cppref。
ABC{}
是臨時的,因此ABC b{ABC{}}
將使用移動構造函數(即使可以使用省略)。
刪除移動構造函數時,您應該收到錯誤。
你的gcc版本有一個錯誤,並沒有通過錯誤的省略來檢測錯誤。
在C ++ 17中,有了保證拷貝省略,甚至刪除了構造函數都可以省略。 因此,您的代碼將在C ++ 17中編譯,只有一個默認構造函數被調用。
編輯:有人將問題標記為重復,但事實並非如此。 我明確表示我認為C ++ 11標准包括復制省略。 但是,CLANG似乎對構造函數的關鍵性沒有相同的行為。
這里是鏈接: http : //en.cppreference.com/w/cpp/language/copy_elision
很明顯,它說的是C ++ 11。 我相信cppref。
是我把它標記為傻瓜。 從您鏈接的頁面:
在下列情況下, 允許編譯器,但不要求省略復制和移動(自C ++ 11)構造
當一個無名的臨時,沒有綁定到任何引用時,將被復制或移動(自C ++ 11)到相同類型的對象(忽略頂級cv資格),復制/移動(從C ++ 11開始) )被省略。 (直到C ++ 17)
這種優化是強制性的 ; 往上看。 (自C ++ 17起)
正如您所看到的那樣,移動構造函數將是必需的,因為復制省略不是必需的,而是C ++之前的建議17。 C ++ 17編譯器不應該在相同的情況下抱怨刪除的移動構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.