首先,我想要一個普通的枚舉而不是基於位的枚舉,因爲不同枚舉的數量將超出任何整數類型。我也想利用C++ 11 enum class
的類型安全性。要做到這一點,自然選擇將是std::bitset
,但我不知道如何將這兩者結合在一起。使用枚舉類與std :: bitset
將需要一個自定義bitset
?如何繞過這樣的課程的實施?
首先,我想要一個普通的枚舉而不是基於位的枚舉,因爲不同枚舉的數量將超出任何整數類型。我也想利用C++ 11 enum class
的類型安全性。要做到這一點,自然選擇將是std::bitset
,但我不知道如何將這兩者結合在一起。使用枚舉類與std :: bitset
將需要一個自定義bitset
?如何繞過這樣的課程的實施?
因爲enum class
es是enums的包裝,所以可以將它們轉換爲基礎類型。
並且使用一些私有繼承,您可以選擇性地從C++ stdlib類中導入一些功能,而不用擔心Liskov的原理。
成分產生更清晰的代碼。使用這些功能,我們可以包裝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";
}
由於enum
都不具備的許多功能很遺憾,並且更重要的是,C++ 11 enum class
ES沒有改善的情況下,some programmers use static map wrapped in a class. Definitely a good read.
嗯,這應該可以做成一個通用的模板,對嗎? –
@KornelKisielewicz是的,這段代碼可以很容易地模板化。只是沒有直接寫模板,因爲我對他們不太滿意:)。 – milleniumbug
好吧,我看到一個潛在的問題 - 有沒有簡單的方法來找到枚舉的最大值(不訴諸增加另一個枚舉值)...所以它可能必須是模板的第二個參數,太安全了:/。 –
我有點不確定你」再問一次你有沒有機會添加一些關於你想要做什麼的細節,或者可能是一個例子? –
從我得到的結果來看,您希望通過枚舉類型安全地(不帶enum-to-int)標誌訪問''std :: bitset''而不是類似類型。我的理解是否正確?確切地說, –
milleniumbug
。基本上我有現有的'enum class'定義,我想把它們打包成一個類型安全的'bitset'。 –