Использование класса enum с std :: bitset

Прежде всего я хочу нормальное перечисление вместо основанного на битах перечисления, потому что количество различных перечислений будет вне любого целочисленного типа. Я также хочу воспользоваться преимуществами безопасности типов в C ++ 11 enum class, Для этого естественным выбором будет std::bitsetОднако я понятия не имею, как связать эти два вместе.

Обычай bitset понадобится? Как обойти реализацию такого класса?

5

Решение

поскольку enum classЭто обертки для перечислений, вы можете привести их к базовому типу. А используя частное наследование, вы можете выборочно импортировать некоторые функции из классов C ++ stdlib, не беспокоясь о принципе Лискова. Композиция привела к более четкому коду. Используя эти функции, мы можем обернуть std::bitset, Следующий код содержит только подмножество функционалов, но он может быть расширен в дальнейшем.

Существует проблема с максимальным значением — вы не можете получить максимальное значение enum class (или я не прав?). Итак, я добавил EnumTraits, Теперь пользователи обязаны специализироваться EnumTraits с постоянным значением max равный максимальному значению enum перед использованием класса.

#include <bitset>
#include <type_traits>

template<typename T>
struct EnumTraits;

template<typename T>
class EnumClassBitset
{
private:
std::bitset<static_cast<typename std::underlying_type<T>::type>(EnumTraits<T>::max)> c;

typename std::underlying_type<T>::type get_value(T v) const
{
return static_cast<typename std::underlying_type<T>::type>(v);
}

public:
EnumClassBitset() : c()
{

}

bool test(T pos) const
{
return c.test(get_value(pos));
}

EnumClassBitset& reset(T pos)
{
c.reset(get_value(pos));
return *this;
}

EnumClassBitset& flip(T pos)
{
c.flip(get_value(pos));
return *this;
}
};

enum class BitFlags
{
False,
True,
FileNotFound,
Write,
Read,
MaxVal
};

template<>
struct EnumTraits<BitFlags>
{
static const BitFlags max = BitFlags::MaxVal;
};

#include <iostream>

int main()
{
EnumClassBitset<BitFlags> f;
f.flip(BitFlags::True);
f.flip(BitFlags::FileNotFound);
//f.flip(2); //fails to compile
std::cout << "Is False? " << f.test(BitFlags::False) << "\n";
std::cout << "Is True? " << f.test(BitFlags::True) << "\n";
std::cout << "Is FileNotFound? " << f.test(BitFlags::FileNotFound) << "\n";
std::cout << "Is Write? " << f.test(BitFlags::Write) << "\n";
std::cout << "Is Read? " << f.test(BitFlags::Read) << "\n";
}

поскольку enumS, к сожалению, не так много функциональности, и, кроме того, C ++ 11 с enum classне улучшай ситуацию, некоторые программисты используют статическую карту, заключенную в класс. Определенно хорошее чтение.

9

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]