Ограниченные, но "полуслабо" типизированные перечисления
Я хочу использовать перечисления в заданном формате, но уметь сравнивать и присваивать целые числа без знака.
Это то, что я попробовал код ниже, который работает, как ожидалось:
class SystemEvents {
public:
enum {
Opened, Closed
};
};
class OtherEvents {
public:
enum {
Closed,Opened
};
};
//test
uint32_t e = SystemEvents::Opened;
if(e == OtherEvents::Closed) std::cout << "enums are weakly typed and scoped";
Но я хочу знать, есть ли способ сделать это с помощью синтаксиса C++11?
enum class SystemEvents : uint32_t {
Opened,Closed
};
enum class OtherEvents : uint32_t {
Closed,Opened
};
//test
uint32_t e = SystemEvents::Opened;
if(e == OtherEvents::Closed) std::cout << "enums are weakly typed and scoped";
Код выше дает мне ошибку, как и ожидалось Cannot initialize a variable of type int with an rvalue of type SystemEvents
, Итак, я должен придерживаться перечислений в стиле C или есть способ сделать это в C++11? Или есть какой-то другой способ сделать это?
2 ответа
Для инициализации вы можете сделать немногое, кроме приведения значения. Обратите внимание, что строго типизированные перечисления в C++11 предназначены не для замены, а для дополнения существующих перечислений. Если вы хотите перечисление со слабым типом, просто не используйте enum class
,
Для сравнения перечисления со строгой типизацией вы можете объявить необходимые операторы и привести внутри реализации:
bool operator==( uint32_t lhs, SystemEvents rhs )
{
return static_cast< SystemEvent >( lhs ) == rhs;
}
Конечно, вам нужны оба направления:
bool operator==( SystemEvents lhs, uint32_t rhs );
И другие операторы, такие как !=
,
Вы можете явно привести класс enum к целочисленному типу, например:
static_cast<uint32_t>(SystemEvents::Opened)
Вы также можете написать функцию, которая будет приводить к базовому типу любого класса enum.
Однако необходимость сделать это предполагает, что вы делаете что-то не так. Почему вы пытаетесь сравнить SystemEvents
с OtherEvents
?