Если у класса есть член с copy-ctor, но не mov-ctor, вызвать содержащий класс, также определенный с удаленным move-ctor? - PullRequest
2 голосов
/ 08 февраля 2020

Я не понял это в C ++ primer 5 ed. :

Например, если предположить, что Y является классом, который определяет свой собственный конструктор копирования, но также не определяет свой собственный конструктор перемещения:

// assume Y is a class that defines its own copy constructor but not a move constructor

struct hasY { hasY() = default; hasY(hasY&&) = default; Y mem; // hasY will have a deleted move constructor }; hasY hy, hy2 = std::move(hy); // error: move constructor is deleted

Компилятор может копировать объекты типа Y, но не может их перемещать. Класс hasY явно запросил конструктор перемещения, который компилятор не может сгенерировать. Следовательно, hasY получит удаленный конструктор перемещения. Если бы hasY пропустил объявление своего конструктора перемещения, то компилятор вообще не синтезировал бы конструктор перемещения hasY. Операции перемещения не синтезируются, если в противном случае они были бы определены как удаленные.

Итак, я определил Y, как он сказал:

struct Y
{
    Y() = default;
    Y(const Y&){std::cout << "Y's Copy-ctor\n";
    Y& operator=(const Y&){std::cout << "Y's copy-assignment operator\n"; return *this;}

};

struct hasY {
    hasY() = default;
    hasY(hasY&&) noexcept = default;
    Y mem; // hasY will have a deleted move constructor
};

В основном:

 hasY hy, hy2 = std::move(hy); // error: move constructor is deleted
  • Но программа работает нормально и не жалуется на удаленный конструктор перемещения, как он сказал?!

Вывод:

Y's copy ctor
  • Как вы видите, программа отлично работает со мной, хотя я тестировал ее на многих компиляторах с разными версиями и с разными флагами компиляции. Я предполагаю, что это ошибка в книге.

  • Я думаю, что класс hasY является подвижным, и его конструктор перемещения не удаляется, потому что вызовы move-ctor перемещают ctor класса Y, который неявно не определен (не удален, но не определен) так что он не может использовать copy-ctor Y. Так что я думаю, что класс Y можно перемещать через конструктор копирования. Таким образом, программа выводит copy-ctor Y.

** В cppreference сказано:

Неявно объявленный или дефолтный конструктор перемещения для класса T определяется как удаленный, если выполняется любое из следующих условий:

T имеет нестатические c элементы данных, которые не могут быть перемещены (имеют удаленные, недоступные или неоднозначные конструкторы перемещения); T имеет прямой или виртуальный базовый класс, который не может быть перемещен (имеет удаленные, недоступные или неоднозначные конструкторы перемещения); T имеет прямой или виртуальный базовый класс с удаленным или недоступным деструктором;

T является объединяющим классом и имеет вариантный член с нетривиальным конструктором перемещения;

T имеет элемент данных c, не содержащий данных, или прямую или виртуальную базу без конструктора перемещения, который нетривиально копируется.

Удаленный неявно объявленный конструктор перемещения игнорируется разрешением перегрузки (в противном случае это предотвратит инициализацию копирования из rvalue).

  • У меня также есть неоднозначность между: «неявно определено как удаленная операция» и «вообще не определено»? Для меня определение как удаленное - это как:

    Y(Y&&) = delete; // generated by the compiler
    

И совсем не определено то же значение выражения.

*** Для подтверждения моего говоря о том, что конструктор перемещения класса hasY не удален, то вот простое:

struct hasY {
    hasY() = default;
    hasY(hasY&&) noexcept = default;
    Y mem; // hasY will have a deleted move constructor
    std::unique_ptr<int> upi; // This really causes hasY non-copy-able
};
  • Как вы можете видеть, я добавил не копируемый объект типа uniqe_ptr для предотвращения копирования hasY и запуска программы, как и прежде, без ошибок, что означает, что конструктор перемещения hasY не удален.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...