Почему объявление конструктора копирования не удаляет оператор присваивания копирования и наоборот?

Итак, если у меня есть класс и я объявляю в нем оператор присваивания копии, очевидно, мне нужно какое-то особое поведение при копировании. Я ожидаю, что язык попытается помочь мне, неявно удалив конструктор копирования, пока я не верну его явно, чтобы избежать непреднамеренного другого поведения при выполнении type instance = type(), а не already_existing_instance = type().

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

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

Мой вопрос: почему компилятор это делает? Кто подумал, что это хорошая идея? Все, что он делает, это создает ненужное препятствие для программиста, или я что-то упускаю?

P.S. Это поведение не проявляется, когда вы делаете то же самое с конструкторами перемещения/операторами присваивания, зачем в этом случае делать различие между копированием и перемещением?

Компиляторы, как правило, получают предупреждение, когда есть пользовательский копирайтер, но не копируют присваивание наоборот. Это наследование от pre-C++11, когда нельзя было выполнить указанные операции по умолчанию.

ALX23z 21.11.2022 18:48

@ ALX23z Можете ли вы уточнить, что вы имеете в виду, когда говорите, что «нельзя выполнять указанные операции по умолчанию»? В моих примерах не используется ключевое слово по умолчанию, вы имеете в виду что-то другое?

Nik Tedig 21.11.2022 18:54

Возможно, однажды timsong-cpp.github.io/cppwp/n4868/…

StoryTeller - Unslander Monica 21.11.2022 18:59

По умолчанию я имею в виду запись = default. Поэтому, когда это невозможно сделать, если, скажем, по какой-то причине ctor копирования по умолчанию был отключен, вам придется написать полную реализацию вручную, даже если вам нужен вариант по умолчанию.

ALX23z 21.11.2022 19:02
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
2
4
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если они не удаляются, они устарели.

Например. Clang 15 с -Wextra, дано

struct A
{
    A() {}
    A(const A &) {}
};

int main()
{
    A a, b;
    a = b;
}

плюется

<source>:4:5: warning: definition of implicit copy assignment operator for 'A' is deprecated because it has a user-provided copy constructor [-Wdeprecated-copy-with-user-provided-copy]
    A(const A &) {}
    ^
<source>:10:7: note: in implicit copy assignment operator for 'A' first required here
    a = b;
      ^

Сходным образом,

struct A
{
    A() {}
    A &operator=(const A &) {return *this;}
};

int main()
{
    A a, b(a);
}

дает

<source>:4:8: warning: definition of implicit copy constructor for 'A' is deprecated because it has a user-provided copy assignment operator [-Wdeprecated-copy-with-user-provided-copy]
    A &operator=(const A &) {return *this;}
       ^
<source>:9:10: note: in implicit copy constructor for 'A' first required here
    A a, b(a);
         ^

Абсолютно фантастично. Просто чтобы убедиться, что я не ошибаюсь, устаревание означает, что они удалят его в будущем, верно?

Nik Tedig 21.11.2022 19:23

@NikTedig Надеюсь, да.

HolyBlackCat 21.11.2022 19:27

@NikTedig - устаревший означает, что он может быть удален в будущем. Это не обещание; это предупреждение.

Pete Becker 21.11.2022 19:48

... или больше угрозы.

Eljay 21.11.2022 21:02

Другие вопросы по теме