С++ 11: объявлен ли пользователь-конструктор копии по умолчанию?

Я думаю, это так, но я ищу юристов на языке С++ 11, чтобы подтвердить мое впечатление. Верно ли, что следующий класс

struct X{
X(){}
X(X const&)=default;
};

не будет автоматически включаться, т.е. получать X(X&&) и operator=(X&&), потому что его конструктор копирования "объявлен пользователем", хотя он выглядит эквивалентно

struct X{
};

который получит как X(X const&), так и X(X&&) и т.д., неявно объявленные и (тривиально) определенные при использовании.

Ответы

Ответ 1

Конструктор

A default ed действительно "объявлен пользователем"; Я думаю, что добавление default на самом деле стало причиной того, что они изменили термин от "пользовательского" до "объявленного пользователем".

Ответ 2

Из стандарта:

8.4.2 Явно-дефолтные функции [dcl.fct.def.default]

4 - [...] Специальная функция-член предоставляется пользователю, если она объявлена ​​пользователем и явно не указана дефолт или удаленный по его первой декларации. [...]

Явное умолчание можно объединить с его объявлением или оно может быть отдельным:

struct S {
    S();
};
S::S() = default;

В любом случае его (первое) объявление делает его объявленным пользователем.

Ответ 3

Да, ваш назначенный по умолчанию оператор присваивания копии исключает неявное перемещение ctor.

BTW put =default на самом деле является определением. Я помню пытаюсь реализовать идиом pimpl с std::unique_ptr и вынужден удалять =default из заголовков и помещать их в файл реализации, потому что деструктор для unique_ptr нужен определение класса, который он пытается очистить.

Ответ 4

Верно, что в §12.8 устанавливаются условия, когда конструктор перемещения неявно объявляется, и это исключает наличие объявленного пользователем конструктора копирования. У вас не может быть

  • объявленный пользователем конструктор копирования
  • пользовательский оператор присваивания копий
  • объявленный пользователем оператор перемещения-назначения
  • объявленный пользователем деструктор