Почему Clang жалуется на удаленный ctor перемещения, когда я ничего не перемещаю? - PullRequest
0 голосов
/ 18 мая 2018

Помещение :

#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 против Clang

Clang - Apple LLVM version 8.1.0 (clang-802.0.42)

Gcc - 5.4.0 ubuntu

Наблюдение Кланг жалуется на удаленный конструктор Move.

Gcc вообще не жалуется.И будет выводить правильно.

Вопрос Почему?

Для gcc я знаю, что если вы просто инициализируете и lvalue, и rvalue, он оптимизирует и фактически не вызываетСкопируйте конструктор и скопируйте временное значение в lvalue.

Почему 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.

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

РЕДАКТИРОВАТЬ: Кто-то пометил вопрос как дуп, а это не так.Я четко заявляю, что считаю, что стандарт 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 не должны жаловаться на удаленный конструктор перемещения при тех же обстоятельствах.

0 голосов
/ 18 мая 2018

ABC{} является временным, поэтому ABC b{ABC{}} будет использовать конструктор перемещения (даже если elision будет возможен).

При удалении конструктора перемещения вы должны получить ошибку.

В вашей версии gcc есть ошибка, и она не обнаруживает ошибку по ошибке.

В C ++ 17 при наличии гарантии на гарантированное копирование может быть исключен даже удаленный конструктор.Таким образом, ваш код будет компилироваться в C ++ 17 только с одним конструктором по умолчанию.

...