Вам нужно пройти через большой код, к сожалению, я не могу выяснить, что на самом деле является ActionType
.
Как вы указали, использование глобальных переменных действительно плохая идея.К счастью, они добавили constexpr
к языку.С constexpr
вы можете создавать константы, которые «определяются» во время компиляции, не оказывая влияния на время выполнения.Таким образом, независимо от того, в каком порядке выполняются ваши Ctors, он даст правильный результат.
С другой стороны, std::initializer_list
не является constexpr (даже в C ++ 20), std::bitset
is.
#include <bitset>
struct ActionType {
static constexpr std::bitset<4> addShard{0b0101};
};
Используя приведенный выше код, вы создали переменную constexpr
, которую можно безопасно использовать для инициализации глобальной переменной.Точно так же вы можете создать свой следующий тип как constexpr
доступны:
class ActionSet {
public:
constexpr ActionSet();
ActionSet(std::initializer_list<int> ids);
constexpr ActionSet(std::bitset<4> actions) : _actions{actions} {}
void dump() const;
private:
std::bitset<4> _actions{0};
};
constexpr ActionSet s(ActionType::addShard);
Короче говоря, до тех пор, пока вы можете «определить» все во время компиляции (включая весь необходимый код в заголовках),Вы можете создавать константы на основе других констант.Вызов постоянных методов для них может быть выполнен позже во время выполнения.
Начиная с C ++ 20, вы должны иметь возможность написать:
[[constinit]] ActionSet s(ActionType::addShard);
Это должно позволить вам использовать не-const методы в вашей программе.Для меня неясно, позволяет ли это по-прежнему использовать 's' в конструкторе следующей переменной constexpr.