[英]Using enum class with std::bitset
首先,我想要一個普通的枚舉而不是基於位的枚舉,因為不同枚舉的數量將超出任何整數類型。 我還想利用C ++ 11 enum class
的類型安全性。 要做到這一點,自然選擇將是std::bitset
,但是我不知道如何將這兩者綁定在一起。
自定義bitset
將需要? 如何繞過這樣一個類的實現?
由於enum class
是枚舉的包裝器,因此可以將它們轉換為基礎類型。
使用一些私有繼承,您可以有選擇地從C ++ stdlib類導入一些功能,而不必擔心Liskov的原理。
組合產生了更清晰的代碼。 使用這些功能,我們可以包裝std::bitset
。 以下代碼僅包含功能的子集,但可以進一步擴展。
最大值存在問題 - 您無法獲得enum class
最大值(或者我錯了?)。 所以我添加了EnumTraits
。 現在,用戶需要專門化EnumTraits
,其const值max
等於枚舉的最大值,然后才能使用類。
#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";
}
由於enum
不幸沒有太多功能,更重要的是,帶有enum class
C ++ 11並沒有改善這種情況, 一些程序員使用包含在類中的靜態映射。 絕對是一個很好的閱讀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.