Задать вопрос
@Zellily

Как изменить значение поля enum в рантайме?

Скажем, есть у меня некоторая функция, которая в какой-то момент времени вернёт либо true, либо false. В зависимости от результата этой функции мне нужно задать значения enum:
Скажем, был такой enum:
enum class Foo{qqq, www };
А стал такой:
Foo::qqq = 5; Foo::www = 10;
(это псевдокод, так работать не будет, но нужно аналогичное по смыслу)

Если так нельзя, то какие вообще варианты возможны в таком случае, если нужен enum со значениями, меняющимися во время работы? Может быть создать два энума с одинаковыми по названию полями, и возвращать указатель на энум в зависимости от true/false функции?
  • Вопрос задан
  • 1419 просмотров
Подписаться 1 Простой 17 комментариев
Пригласить эксперта
Ответы на вопрос 3
@res2001
Developer, ex-admin
enum - это константы.
Если у вас всего 2 варианта значений, то добавьте в enum дополнительные значения:
enum class Foo{qqq = 0, www = 1, qqq1 = 5, www1 = 10 };
Если больше - нужно менять схему и использовать не enum.
Ответ написан
GavriKos
@GavriKos
Чисто на енамах - никак. После компиляции енама нет - там просто инты.
Самый простой вариант в данном случае - map. Ключ - строка (или можете тот же енам использовать, если вам удобнее), значение - текущее значение собсно.
Ответ написан
Вам нужны tagged union. Вот как это выглядело бы на Swift, например:

enum Foo {
    case qqq(Int)
    case www(Int)
}

let x = Foo.qqq(5)
let y = Foo.www(10)


На C++ это часто эмулируется с помощью наследования:

class Foo {
public:
    virtual ~Foo() = 0;
};

class qqq : public Foo {
public:
    int value;
    explicit qqq(int value);
};

class www : public Foo {
public:
    int value;
    explicit www(int value);
};

using FooPtr = std::unique_ptr<Foo>;
FooPtr makeQqq(int value);
FooPtr makeWww(int value);

FooPtr x = makeQqq(5);
FooPtr y = makeWww(10);


Я опустил небольшое количество кода, который, я не сомневаюсь, вы могли бы сами закончить, если действительно хотите заставить этого монстра работать :)

Есть и более чистый способ: подключите либу type_safe (кликабельно).

#include <type_safe/strong_typedef.hpp>
#include <type_safe/variant.hpp>

namespace ts = type_safe;

using qqq = ts::strong_typedef<int>;
using www = ts::strong_typedef<int>;
using Foo = ts::variant<qqq, www>;

// ...

auto x = Foo(qqq(5));
auto y = Foo(www(10));

if (x.has_value(ts::variant_type<qqq>{})) {
    qqq value = x.value(ts::variant_type<qqq>{}));
    std::cout << "qqq" << ' ' << static_cast<int>(value);
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы