Неявно объявленные Move-Operations не отступают от Copy? - PullRequest
6 голосов
/ 17 сентября 2011

Должен ли я прочитать N3291 "12.8. (15.11.28) Копирование и перемещение объектов класса class.copy]" исправить то, что неявно объявленный конструктор перемещения

  • выполняет поэлементное перемещение всех нестатических элементов данных (вероятно, через соответственно определенные T(T&&)
  • и если какой-либо нестатический элемент данных не может быть перемещен, неявный конструктор перемещения будет помечен как удаленный и не будет пытаться скопировать как "запасной вариант"? (да, перемещение определено для встроенных типов, но на самом деле это копия).

и аналогично move-assign , используя соответствующие T operator=(T&&) элементов.

Пример: * * один тысяча двадцать-одна

struct CopyOnly {
    CopyOnly();
    CopyOnly(const CopyOnly&);
}; // declaring a copy means no implicit move.

struct Question {
    std::vector<int> data_;
    CopyOnly         copyOnly_;
};

класс Question

  • будет иметь неявно объявленный конструктор копирования и assign
  • будет иметь неявно объявленные move-constructor и move-assign , , но они будут =delete d , потому что нестатические данные- элемент data_ является только копируемым , но не подвижным ?

Обновление. Дополнительный вопрос: для Question q; будет ли std::move(q) все еще работать? Будет ли запасной вариант для копирования там? Или неявно объявленный move-ctor заставит компилятор остановиться с ошибкой? Здесь он компилируется.

Обновление 2. Что генерирует компилятор для неподвижных элементов данных, если я объявляю move-ctor Question(Question&&) =default? тогда отступает к копированию тех?

1 Ответ

5 голосов
/ 17 сентября 2011

Вы прочитали это неправильно. Это сломало бы много классов C ++ 03 в таких случаях, как следующие

Question getQuestion();
Question q(getQuestion()); // use of deleted move constructor!

Вместо этого FDIS сообщает, что конструктор перемещения будет объявлен тогда и только тогда, когда пользователь не объявил {конструктор копирования, оператор присваивания {copy, move}, деструктор} и неявно объявленный конструктор перемещения не будет определен как удален }.

Относительно Обновление 2 . До моего сведения дошло, что если вы явно укажете конструктор перемещения по умолчанию, он будет определен как удаленный из условия

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

В дальнейшем конструктор перемещения будет определен как Удалено , поскольку CopyOnly не может быть легко скопировано.

 struct Question 
 {
        std::vector<int> data_;
        CopyOnly         copyOnly_;

        Question(Question&&) = default;
 };
...