Почему clang думает, что у меня есть конструктор копирования?

У меня есть структура с этими специальными функциями-членами:

struct MyStruct {
    MyStruct(MyStruct& other) = delete;

    MyStruct(MyStruct&& other) = default;

    explicit MyStruct(int num) noexcept(false);

    explicit MyStruct(MyOtherStructType&& other_type);

    ~MyStruct();

    auto operator=(MyStruct&& other) noexcept(false) -> MyStruct&;
}

Clang Tidy говорит:

Class 'MyStruct' defines a non-default destructor, a copy constructor, a move
constructor and a move assignment operator but does not define a copy assignment
operator

Но из-за ворса hicpp-special-member-functions/cppcoreguidelines-special-member-functions я думал, что удалил конструктор копирования? Я что-нибудь пропустил? Ворс неправильный?

Он жалуется на оператор присваивания копирования, который вы не определили.

François Andrieux 27.07.2024 02:43

Да, меня это не волнует, я хочу знать, почему он думает, что у меня есть конструктор копирования.

Camden Narzt 27.07.2024 02:46

У вас есть один. Он удален, а значит ошибка в его использовании, но он есть.

Raymond Chen 27.07.2024 02:59

Это может сбить с толку, поскольку аргумент вашего конструктора копирования не является константным, что нетипично.

François Andrieux 27.07.2024 03:03

@RaymondChen он там, как указано в коде, как недоступный? Мне это кажется странным определением «определенного».

Camden Narzt 27.07.2024 03:12

«Определено как удаленное» отличается от «не определено».

Raymond Chen 27.07.2024 03:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Правило пяти применяется ко всем другим специальным функциям-членам после того, как вы явно объявляете любую специальную функцию-член, а не только тогда, когда вы предоставляете для нее собственное определение. Определение функции как удаленной по-прежнему учитывается.

Обратите внимание, что определение функции как удаленной — это не то же самое, что отсутствие объявления функции вообще (неявно или явно). Функция, определенная как удаленная, по-прежнему объявляется и участвует в разрешении перегрузки как обычно. Единственное значение, которое это имеет, заключается в том, что если разрешение перегрузки выберет удаленную функцию, то разрешение перегрузки будет считаться неправильно сформированным.

Причина, по которой правило также должно применяться при удалении конструктора копирования, заключается в том, что удаление конструктора копирования не препятствует неявному определению оператора присваивания копирования.

Но если вы явно удалили конструктор копирования, то вполне вероятно, что ваш тип также не должен иметь семантику копирования по умолчанию при назначении. Правило пяти гарантирует, что вы не забудете объявить правильную семантику для оператора присваивания копии, который, если вы хотите, можно объявить значениями по умолчанию для компилятора, определив перегрузку как = default.

Как бы то ни было, написание

MyStruct x(1);
MyStruct y = x;

имеет неправильную форму, но

MyStruct x(1);
MyStruct y(2);
y = x;

будет компилироваться с поведением копирования по умолчанию, сгенерированным компилятором, что, вероятно, неверно для вашего типа, если вы удалили конструктор копирования.


Кроме того, конструктор копирования или оператор присваивания копирования должен принимать свой параметр в качестве ссылки const. Несоблюдение этого соглашения вызовет у вас проблемы. Поскольку удаленная перегрузка по-прежнему участвует в разрешении перегрузки, по-прежнему имеет значение, использует ли она const.

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