Было ли установлено, что конструктор / назначение перемещения / копирования «удален» или «не объявлен» в C ++ 17? - PullRequest
9 голосов
/ 12 мая 2019

Я смотрел на этот ответ относительно Каковы правила автоматической генерации операций перемещения? , и я надеюсь, что ответ к настоящему времени уже хорошо известен.

На слайде, показывающем, какие конструкторы / операторы присваивания «не объявлены», «по умолчанию» или «удалены» на основе того, что было объявлено в классе, показано:

enter image description here

Это было взято из этих слайдов , где красные квадраты означают, что это поведение устарело.

При компиляции следующего:

#include <iostream>
struct X
{
  template<typename...T>
  X(T&&...) {
    std::cout << "Yay!\n";
  }

  ~X() {}
};

int main() {
  X x0;
  X x1{x0};
  X x2{std::move(x0)};
}

Может показаться, что они были "не объявлены", так как он компилируется и выводится "Yay!"три раза (что хорошо, по крайней мере для меня).Но я хочу подтвердить, что могу положиться на это поведение.

Редактировать

Frank указал, что, если также добавляется конструктор копирования, онвсе еще говорит "Yay!"три раза, что интересное поведение.При дальнейшем тестировании, если добавлен конструктор перемещения, он скажет только «Yay!»дважды.Кто-нибудь может объяснить это поведение?

1 Ответ

2 голосов
/ 12 мая 2019

Согласно N4659 (почти стандарт C ++ 17), они все еще определены как дефолтные, но поведение (все еще) устарело.

Если определение класса не объявляет явно конструктор копирования, неявный неявный объявляется.Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный конструктор копирования определяется как удаленный;в противном случае определяется как дефолтный.Последний случай устарел , если у класса есть пользовательский оператор копирования или пользовательский деструктор.

Если определение класса явно не объявляет оператор присваивания копии, он объявляется неявно.Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный оператор присваивания копии определяется как удаленный;в противном случае определяется как дефолт.Последний случай устарел , если у класса есть пользовательский конструктор копирования или деструктор, объявленный пользователем.

...