簡體   English   中英

為什么當我不移動任何東西時,clang會抱怨刪除的移動?

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

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