Наследование оператора = и конструктора, но также добавление дополнительного назначения оболочки

У меня есть следующая структура:

struct Feedback : public TaggedUnion<Feedback1Idx, String>
{
    using TaggedUnion<Feedback1Idx, String>::TaggedUnion;
    using TaggedUnion<Feedback1Idx, String>::operator=;

    bool isError = false;
};

... который наследует оператор TaggedUnion =, что позволяет мне написать следующее:

Feedback a = Feedback1Idx();
Feedback b = String();
Feedback c = Feedback();
Feedback d = b;

В приведенных выше примерах я хотел бы, чтобы a.isError было истинным, b.isError — истинным, но c.isError — ложным (и d.isError — истинным, потому что b.isError — истинным). Другими словами, каждый раз, когда используется унаследованный оператор =, я хотел бы, чтобы .isError был переключен на true.

Как я могу этого добиться? (без добавления конструктора/оператора присваивания для каждого параметра шаблона, который я добавляю в TaggedUnion<>)

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

Some programmer dude 16.02.2023 13:46

Вы достигаете этого, определяя явный оператор присваивания вместо его наследования?

Sam Varshavchik 16.02.2023 13:53

@SamVarshavchik Действительно, однако в будущем я добавлю больше параметров шаблона в TaggedUnion<>, поэтому я бы хотел, чтобы это было автоматически, если это возможно. Я не против определения своего собственного оператора, это больше о том, «как мне определить его таким образом, чтобы он охватывал унаследованный оператор?» согласно названию; в противном случае это означало бы, что мне придется добавлять перегрузку каждый раз, когда я добавляю параметр в TaggedUnion<>

ZeroZ30o 16.02.2023 14:15

@Someprogrammerdude Это правда, однако возникают те же проблемы, но с конструкторами вместо операторов присваивания. В идеале я бы определил одинаковое поведение для них обоих.

ZeroZ30o 16.02.2023 14:19

Итак, ваш пользовательский оператор вызывает TaggedUnion::operator= явно?

Sam Varshavchik 16.02.2023 14:27

@SamVarshavchik Верно, но каков синтаксис для TaggedUnion::operator= и TaggedUnion::TaggedUnion в Feedback?

ZeroZ30o 16.02.2023 14:34
TaggedUnion<Feedback1Idx, String>::operator= и TaggedUnion<Feedback1Idx, String>::TaggedUnion, как показано в коде.
Sam Varshavchik 16.02.2023 14:36

ZeroZ30o 16.02.2023 14:37

Существуют различные методы решения этой проблемы с использованием шаблонов. Это был бы отдельный вопрос. На этот вопрос: нет, вы не можете определить такой оператор присваивания, С++ так не работает.

Sam Varshavchik 16.02.2023 14:39

@SamVarshavchik Это не отдельный вопрос. Вот этот вопрос. Это буквально то, о чем я прошу... Решение вышеуказанной проблемы, которое будет включать шаблоны (потому что я не хочу использовать виртуальные).

ZeroZ30o 16.02.2023 14:40

Вопрос относится к оператору присваивания, а не к какому-либо конструктору, как в вашем предыдущем комментарии. Операторы присваивания не являются конструкторами.

Sam Varshavchik 16.02.2023 14:42

@SamVarshavchik Именно из-за такого поведения людям не нравится stackoverflow. Люди, у которых есть проблема, очевидно, не определяют свою проблему с точностью учебника, потому что если бы у них была точность учебника, у них не было бы проблемы. Если вы не собираетесь отвечать на вопрос, это нормально. Но если вам это так нужно, я могу добавить «как я могу добиться этого БЕЗ ОБЪЯВЛЕНИЯ НОВОГО ОПЕРАТОРА КАЖДЫЙ РАЗ, КОГДА Я ДОБАВЛЯЮ ПАРАМЕТР», если это удовлетворяет ваше снобистское поведение. Кроме того, это относится к конструкторам так же, как и к операторам присваивания, поскольку они оба делают одно и то же, так что это не имеет значения.

ZeroZ30o 16.02.2023 14:45

Первоначальный вопрос заключался в следующем: «Каждый раз, когда используется унаследованный оператор =, я бы хотел, чтобы .isError был переключен на true». Я вполне доволен тем, что пусть все остальные судят, будет ли эта интерпретация разумно выведена из этого. Насколько я понимаю: есть ли где-нибудь волшебная палочка, от которой можно отказаться, чтобы унаследованный оператор = работал так? Ответ по-прежнему «нет», простой и короткий.

Sam Varshavchik 16.02.2023 14:52

@SamVarshavchik Снова. Я не отрицаю, что наиболее объективная интерпретация вопроса отличалась от того, что вы утверждаете. Я просто утверждаю, что вы пытаетесь максимально приблизиться к вопросу, не принимая во внимание, что люди могут не идеально выразить свою проблему с первой попытки. Пожалуйста, будьте более практичными, а не педантичными. Несмотря на это, я отредактировал вопрос сейчас, для вашего удовольствия.

ZeroZ30o 16.02.2023 14:55

К сожалению, альтернатива «быть как можно ближе к вопросу» — это пустая трата времени. Например, конструктор шаблона, который участвует в разрешении перегрузки, только если тип шаблона является одним из типов TaggedUnion, довольно прост. Но это работает только в том случае, если нет необходимости поддерживать неявные преобразования ни к одному из них. Требуется ли поддержка неявного преобразования? Только ты это знаешь. Итак, допустим, я трачу время на написание этого конструктора. Вы пробуете это и обнаруживаете, что теперь куча вещей не компилируется. Я потерял много времени.

Sam Varshavchik 16.02.2023 16:36

Хммм... Кажется, именно об этом были мои предыдущие комментарии: больше информации и пояснений. В любом случае, я с нетерпением жду возможности увидеть, каким оказалось ваше решение.

Sam Varshavchik 16.02.2023 17:48

Ну, как я объяснил: C++ не так прост. Вы не указали, должен ли перегруженный шаблон участвовать в разрешении перегрузки, если только параметр шаблона не может использоваться явно или неявно для создания одного из вариантов значений. Ваш ответ не ограничивает участие в разрешении перегрузок, что в конкретной ситуации приводит к сбоям компиляции. К сожалению, из-за отсутствия минимального воспроизводимого примера, который любой может вырезать/вставить и проверить, авторитетный ответ был бы невозможен без доступа к полному коду. Который есть только у тебя.

Sam Varshavchik 17.02.2023 00:50

Ну да, я сделал. До сих пор нет способа заставить унаследованную = перегрузку через директиву using работать так, как вы хотели, чтобы она работала. Во всяком случае, требуется определяемая пользователем перегрузка =. Как в вашем ответе. И никто тебя ни в чем не упрекал. Я просто заявил, что отказываюсь пытаться угадать и заполнить пробелы, делая необоснованные предположения.

Sam Varshavchik 17.02.2023 01:14
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
1
18
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я нашел простое решение:

struct Feedback : public TaggedUnion<Feedback1Idx, String>
{
    bool isError = false;

    Feedback() = default;

    Feedback(const Feedback& _other) = default;

    template<typename TYPE>
    Feedback(const TYPE& _other)
    : TaggedUnion<Feedback1Idx, String>(_other)
    {
        this->isError = true;
    }

    Feedback& operator=(const Feedback& _other) = default;
    
    template<typename TYPE>
    Feedback& operator=(const TYPE& _other)
    {
        this->isError = true;
        TaggedUnion<Feedback1Idx, String>::operator=(_other);
        return *this;
    }
};

Небольшое замечание: компилятор, вероятно, будет кричать на вас, если вы попытаетесь сделать Feedback a = int или какой-либо другой тип, не входящий в унаследованный тип.

В остальном должно быть все хорошо (немного проверял).

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