Страницы

Поиск по вопросам

вторник, 30 октября 2018 г.

Класс для перечисления с заданным типом C++

Если в С++ сделать
enum operation = {plus, minus, mult, div};
То перечисляемые константы буду иметь тип operation.
А если мне нужно, чтобы переменная operation была типа char, и могла принимать только значения {'+', '-', '*', '/'} ?
Есть ли в std/Qt/boost/другой библиотеке какой-либо контейнер, который позволяет делать что-то в духе:
Enumeration operation = {'+', '-', '*', '/'};
Или необходимо писать велосипед самому? Может, что-то есть на эту тему из области шаблонов проектирования?
Upd: Или, еще лучше, если перечисляемые значения могут быть разного типа. К примеру, при разборе строки с арифметическим выражением на токены, токен может быть типов Operator, Operand или Bracket. Как-то так:
Enumeration Token = {op, num, br};


Ответ

Нет, ни в C++, ни в boost&Qt такого контейнера нет. Нет его по одной простой причине — в C++ нет одного общего типа как, скажем в C#&Java. Поэтому, просто невозможно создать контейнер, который будет принимать разнородные данные. Можно, конечно, создать std::vector(QList и вариации) но это, мягко говоря, не лучшее решение, т.к. всё равно придётся «помнить», что там за данные, иначе извлечь их не получится.
Поэтому, такие задачи решаются введением одного общего предка, а все вариации являются его наследниками. Создаётся контейнер указателей на этого предка и в него помещаются нужные потомки. К примеру, у Вас может быть std::vector> vec; и в него Вы будете помещать Ваши конкретные объекты:
vec.push_back(std::make_shared());
Но лучше это всё вынести в ещё одну абстракцию, которая будет представлять собой контейнер, а не использовать «голый» вектор.
Вообще, это довольно обширная тема, которую в рамках ответа не так просто и раскрыть.

Но если просто взять Ваш пример из вопроса, то его можно легко написать так:
std::tuple Token = std::make_tuple(op, num, br);
Хотя, я полагаю, Вам всё же нужен будет более широкий функционал и динамизм, который не достижим с помощью std::tuple. Если моё предположение верно, то для Вас подходит первая часть ответа.

Комментариев нет:

Отправить комментарий