C++ - clang tidy жалуется на правило X?

Этот код вызывает предупреждение в clang tidy:

Класс «Locker» определяет деструктор не по умолчанию, но не определяет конструктор копирования, оператор присваивания копии, конструктор перемещения или оператор присваивания перемещенияclang-tidy(cppcoreguidelines-special-member-functions)

Это обновленная структура, согласно комментариям:

struct Locker
{
    std::binary_semaphore *sem = nullptr;

    // ----------------------------------
    // Methods
    // ----------------------------------
    auto try_lock(std::binary_semaphore &sem_, u32 time_in_seconds = 1) -> bool;

    auto manual_release() -> void;

    // ----------------------------------
    // Deleted
    // ----------------------------------

    Locker(Locker &) = delete;

    Locker(Locker &&) = delete;

    Locker(std::binary_semaphore &&sem_) noexcept = delete;

    Locker(std::binary_semaphore &sem_) noexcept = delete;

    Locker(std::binary_semaphore *sem_) noexcept = delete;

    Locker() noexcept = default;

    auto operator=(std::binary_semaphore &sem_) noexcept -> Locker & = delete;

    auto operator=(std::binary_semaphore &&sem_) noexcept -> Locker & = delete;

    auto operator=(std::binary_semaphore *sem_) noexcept -> Locker & = delete;

    // ----------------------------------
    // Destructor
    // ----------------------------------
    ~Locker()
    {

        manual_release();
    }
};

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

Обратите внимание, что GCC 12.2 с

-Wall -Wextra -pedantic -pedantic-errors -Werror -Wuninitialized -Wtrivial-auto-var-init -Wshadow -Wnormalized -Wno-error=comment

даже не мешает.

Как подавить это предупреждение?

Спасибо!

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

Ниже приведена ссылка на Godbolt, чтобы воспроизвести ситуацию, может ли кто-нибудь исправить мой код и поделиться ссылкой здесь? Ссылка на проблему со структурой clang-tidy

вместо подавления я бы определил их. Может быть, = default уже достаточно, вы пробовали это?

463035818_is_not_a_number 17.02.2023 09:50

@463035818_is_not_a_number подойдет прямо сейчас

LeXav 17.02.2023 09:51

@ 463035818_is_not_a_number : значение по умолчанию повышается: только специальные функции-члены и операторы сравнения могут быть заданы по умолчаниюclang (default_special_members)

LeXav 17.02.2023 09:53

Конструктор и оператор по значению устарели, на них уже распространяется ссылка на константу — при реализации обоих вы столкнетесь с двусмысленностью.

Aconcagua 17.02.2023 09:55

@Aconcagua: я улучшил код в соответствии с вашим замечанием; Я отражу это в посте

LeXav 17.02.2023 09:56

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

463035818_is_not_a_number 17.02.2023 09:58

Конструктор ссылки на R-значение, вероятно, не имеет смысла, даже если вы реализуете другие, по-видимому, Locker в любом случае не становится владельцем объекта.

Aconcagua 17.02.2023 09:58

@Aconcague Я имею в виду свое предложение =default специальным членам, а не подавлению предупреждения, а не конструкторам, уже присутствующим в коде.

463035818_is_not_a_number 17.02.2023 10:00

Теперь вопрос в том, как вы хотели бы обрабатывать копирование/назначение. Должен ли сам Locker копироваться? В настоящее время вы разрешаете неявные конструкторы перемещения и копирования, хотя неясно, имеет ли это смысл, учитывая удерживаемый семафор, и деструктор, вероятно, освободит его, пока конструктор получит его.

Aconcagua 17.02.2023 10:01

@ 463035818_is_not_a_number А, понятно. Тогда ответ автора вопроса был отвлекающим маневром ;)

Aconcagua 17.02.2023 10:02

Если я удалю деструктор, Clang больше не будет жаловаться

LeXav 17.02.2023 10:03

Я думаю, что решающим моментом здесь является то, что правило 5 важно не только для аккуратного лязга. Это важно для людей, читающих ваш код. Если вы реализуете один, вы должны предоставить и другие. Если вы этого не сделаете, то, вероятно, в вашем коде есть ошибка, и даже если это не так, это сбивает с толку, потому что ожидается правило 5. Правило настолько важно, что я бы предпочел добавить какой-нибудь код, который ничего не делает, например, избыточный special_member() = delete; или speical_member() = default;. Если вы придерживаетесь правила 5, то также исчезнет предупреждение о лязгах.

463035818_is_not_a_number 17.02.2023 10:05

@Aconcagua: Locker нельзя скопировать, он просто берет указатель на семафор с помощью метода try_lock (здесь не показан). затем, когда область достигает конца, она автоматически освобождает семафор. Больше ничего

LeXav 17.02.2023 10:06

если нельзя скопировать, то почему нет Locker(const Locker&) = delete; ?

463035818_is_not_a_number 17.02.2023 10:07

В значительной степени то, что я предположил из именования, факта хранения семафора и вывода деструктора;) Тогда вам действительно нужно Locker(Locker const&) = delete избавиться от конструктора копирования по умолчанию. Это само по себе уже удалит конструктор перемещения, хотя может иметь смысл действительно иметь возможность перемещать объекты этого типа — тогда вы бы определили такой — убедившись, что указатель перемещаемого объекта снова установлен на nullptr.

Aconcagua 17.02.2023 10:09

Добавление шкафчика (const Locker &) = удалить; и Locker(const Locker &&) = удалить; предупреждение все еще здесь

LeXav 17.02.2023 10:09
const Ссылки на r-значения довольно бессмысленны, если не считать некоторых очень специфических особых случаев — конструктор перемещения по умолчанию принимает неконстантные Locker&& — хотя при его удалении в любом случае это не имеет большого значения.
Aconcagua 17.02.2023 10:11
Locker(const Locker &&) неверно, удалите const.
n. m. 17.02.2023 10:12

Я обновил структуру в соответствии с вашими комментариями

LeXav 17.02.2023 10:12

Вам также нужно сделать то же самое с назначением копирования/перемещения.

n. m. 17.02.2023 10:13

Вам все еще нужно сделать то же самое для оператора присваивания: Locker& operator=(Locker const&) = delete.

Aconcagua 17.02.2023 10:14

И вам не нужно удалять никакие нестандартные конструкторы — если вы их просто не определите, они не будут существовать. Итак, все, что вам действительно нужно — кроме удаленных стандартных конструкторов/присваиваний копирования/перемещения (тех, которые принимают какую-то ссылку на Locker), — это конструктор, принимающий ссылку или указатель (в зависимости от того, что вы считаете более значимым, я лично склоняюсь к ссылке). в то время как вы просто можете удалить все остальные, принимающие любую константную ссылку на семафор или указатель.

Aconcagua 17.02.2023 10:17

Я удалил все константы, но все равно получил предупреждение. Позвольте мне обновить в моем посте

LeXav 17.02.2023 10:18

@Aconcagua позвольте мне попробовать это

LeXav 17.02.2023 10:19

Резюме: все, что вам действительно нужно, это: Locker(std::binary_semaphore& s) : sem(&s) { } Locker(Locker const&) = delete; Locker& operator=(Locker const&) = delete - удаление конструктора перемещения и присваивания не является обязательным, они все равно будут удалены (путем определения, установки по умолчанию или удаления варианта копирования), но, конечно, вы все равно можете добавить их для большей ясности. ..

Aconcagua 17.02.2023 10:20

Любая комбинация все равно приведет к предупреждению. Это сводит меня с ума

LeXav 17.02.2023 10:21

Вы также удалили const из конструктора/назначения копирования — обратите внимание: ссылка на l-значение -> const -> копировать, ссылка на r-значение -> неконстантное -> перемещение!

Aconcagua 17.02.2023 10:32

Ко всему добавил ссылку на компилятор godbolt, все варианты с clang tidy и тд, может кто поправит мой код и поделится ссылкой?

LeXav 17.02.2023 10:39

Смотрите фиксированный вариант здесь.

Aconcagua 17.02.2023 10:58

Демонстрация передвижного шкафчика — если это кажется вам значимым. Возможно, это не очень актуально здесь, но вы можете вспомнить шаблон для других целей в будущем;)

Aconcagua 17.02.2023 11:10

о, круто, я не знал, что Godbolt может звенеть аккуратно, это сильно упрощает задачу :)

463035818_is_not_a_number 17.02.2023 12:13

@Aconcagua: большое спасибо, жаль, что я не могу проголосовать

LeXav 17.02.2023 12:55
Стоит ли изучать 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
32
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

В основном с помощью Аконкагуа и н.м. мы выяснили, в чем заключалось ваше заблуждение.

У этого неправильная подпись:

Locker( Locker &) = delete;

Конструктор копирования принимает const Locker&. И вы не delete задание. Это пятёрка:

Locker(const Locker &) = delete;
Locker(Locker &&) = delete;
Locker& operator=(const Locker&) = delete;
Locker& operator=(Locker&&) = delete;
~Locker() { 
    std::cout << "";
 }

Если вы явно объявите их все, предупреждение должно исчезнуть: https://godbolt.org/z/eP8TrE9b1

Большое спасибо! То же самое для Аконкагуа, но я не могу проголосовать

LeXav 17.02.2023 12:55

@LeXav Я добавил несколько кредитов к ответу. Я в основном просто писал вещи из комментариев в ответ

463035818_is_not_a_number 17.02.2023 12:57

Спасибо, хороший ход с твоей стороны

LeXav 17.02.2023 15:19

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