Kor*_*icz 7 c++ c++11 enum-class std-bitset
首先,我想要一个普通的枚举而不是基于位的枚举,因为不同枚举的数量将超出任何整数类型.我也想利用C++ 11的类型安全性enum class.要做到这一点,自然的选择是std::bitset,但我不知道如何将这两者结合在一起.
需要定制bitset吗?如何绕过这样一个类的实现?
mil*_*bug 10
由于enum classes是枚举的包装器,因此可以将它们转换为基础类型.使用一些私有继承,您可以有选择地从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";
}
Run Code Online (Sandbox Code Playgroud)
由于enums不幸没有太多功能,更重要的是,带有enum classes的C++ 11 并没有改善这种情况,一些程序员使用包含在类中的静态映射.绝对是一个很好的阅读.
| 归档时间: |
|
| 查看次数: |
4839 次 |
| 最近记录: |