Как я могу выбрать одну из объявленных структур и создать псевдоним?

enum class Color { RED, BLACK };
enum class TreeModel { AVL, RED_BACK, SPLAY }

struct BasicNode {
    BasicNode* left;
    BasicNode* right;
    BasicNode* parent;
};

struct SplayNode : BasicNode {
    
}

struct RBNode : BasicNode {
    Color color;
};

struct AVLNode : BasicNode {
    unsigned int height;
};

....

???? node_;

if (condition == 1)
   node = new AVLNode;
else if (condition == 2)
   node = new RBNode;
else
   node = new SplayNode;

как сделать выбор типа структуры

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

Каков ожидаемый результат? Также нам нужен минимальный воспроизводимый пример

user12002570 09.07.2024 12:26

«я только начал изучать c++...» Хорошая книга по c++

user12002570 09.07.2024 12:28

Чего вы надеетесь достичь, сделав деревья RB и деревья AVL одним классом? Это кажется мне ужасной, ужасной идеей.

Sneftel 09.07.2024 12:28

Каковы условия отбора? То есть какова связь между параметром шаблона и объявленными структурами? Как вы собираетесь выбирать одну из структур вручную (на бумаге)? На данный момент вопрос неясен.

user12002570 09.07.2024 12:29

используя Node = ????

vansergh 09.07.2024 12:39

@vansergh Мы не знаем, для чего вам нужен псевдоним Node. Поэтому нет возможности ответить на ваш вопрос. То есть Node = ???? недостаточно для ответа на ваш вопрос.

user12002570 09.07.2024 12:45

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

vansergh 09.07.2024 12:46

Вы можете использовать constexpr if. Есть и другие способы. Но для этого вам нужно будет уточнить вопрос.

user12002570 09.07.2024 12:46

??КАК???ТИП?? узел_; если (условие == 1) узел = новый AVLNode; иначе, если (условие == 2) узел = новый RBNode; еще узел = новый SplayNode;

vansergh 09.07.2024 12:47

@vansergh Вы можете просто написать BasicNode* node;, так как это основа всех трех показанных структур.

user12002570 09.07.2024 12:48

и я смогу использовать параметры AVLNode? узел.высота?

vansergh 09.07.2024 12:48

@v Вам придется использовать node->height, так как теперь это указатель. Также я бы порекомендовал продолжить чтение книг, на которые я дал ссылку, поскольку все это будет описано в одной из глав.

user12002570 09.07.2024 12:49

автоматический узел = новый AVLNode;

vansergh 09.07.2024 12:50

@vansergh auto это не то, что ты думаешь. Это тип заполнителя. Тип auto выводится из инициализатора. Посмотрите книги, поскольку эти книги помогут вам прояснить ваш вопрос, и тогда вам будет легче увидеть проблему с данным кодом.

user12002570 09.07.2024 12:51

Узел BasicNode* = новый AVLNode; узел-> высота = 10; // 'struct BasicNode' не имеет элемента с именем 'height'

vansergh 09.07.2024 12:53

У этих деревьев гораздо меньше общего, чем вы думаете. Вы, вероятно, заметите это, если сначала реализуете их отдельно.

molbdnilo 09.07.2024 12:53

Все ваши узлы происходят от BasicNode, поэтому вы можете иметь BasicNode * node, а затем присвоить nodenew AVLNode, new RBNode и т. д., при этом используя необработанные указатели в боте, рекомендованные в современном C++. Вместо этого используйте интеллектуальный указатель.

wohlstad 09.07.2024 12:53

std::unique_ptr?

vansergh 09.07.2024 12:58

или может быть союз?

vansergh 09.07.2024 13:01

или станд::вариант?

vansergh 09.07.2024 13:02

@vansergh Обратите внимание, что это не дискуссионный форум. Все подробности должны быть указаны в вашем вопросе. Также вы можете просто записать предыдущие три комментария (unique_ptr, Union и т. д.) в один комментарий. Вы не уточняете свой вопрос, а спрашиваете о случайных конструкциях С++. Это не имеет никакого отношения к вопросу.

user12002570 09.07.2024 13:02

Эта конструкция в корне ошибочна. AVLNode::left теперь BasicNode*, но должно быть AVLNode*. Вы не можете иметь смешанные деревья.

MSalters 09.07.2024 13:47
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
22
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

    enum class Color { BLACK, RED };
    enum class TransplantMode { DEFAULT, LEFT, RIGHT };
    enum class TraverseMode { CONTINUOUS, RECURSIVE };
    enum class TreeModel { SPLAY, RED_BLACK, AVL };

....

    template <class DataType>
    class BaseNode {
    public:
        DataType data;
    };

    template <class DataType>
    class SplayNode : public BaseNode<DataType> {
    public:
        SplayNode<DataType>* left;
        SplayNode<DataType>* right;
        SplayNode<DataType>* parent;
    };

    template <class DataType>
    class AVLNode : public BaseNode<DataType> {
    public:
        AVLNode<DataType>* left;
        AVLNode<DataType>* right;
        AVLNode<DataType>* parent;
        unsigned int height;
    };

    template <class DataType>
    class RBNode: public BaseNode<DataType> {
    public:
        RBNode<DataType>* left;
        RBNode<DataType>* right;
        RBNode<DataType>* parent;
        unsigned int height;
    };

....

    template <class DataType, class NodeType, const TreeModel model>
    class BaseTree {

       ....

    }

    template <class DataType>
    class RBTree : private BaseTree<DataType, RBNode<DataType>, TreeModel::RED_BLACK> {

       ....
         
    };

    template <class DataType>
    class AVLTree : private BaseTree<DataType, AVLNode<DataType>, TreeModel::AVL> {

       ....
         
    };

    template <class DataType>
    class SplayTree : private BaseTree<DataType, SplayNode<DataType>, TreeModel::SPLAY> {

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

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

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