将enum类与std::bitset一起使用
Using enum class with std::bitset
首先,我想要一个普通枚举,而不是基于位的枚举,因为不同枚举的数量将超过任何整数类型。我还想利用C++11enum class
的类型安全性。要做到这一点,自然的选择是std::bitset
,但我不知道如何将两者结合在一起。
是否需要自定义bitset
?如何实现这样一个类?
由于enum class
es是枚举的包装器,因此可以将它们强制转换为底层类型使用一些私有继承,您可以选择性地从C++stdlib类导入一些功能,而无需担心Liskov的原理组合产生了更清晰的代码。使用这些功能,我们可以包装std::bitset
。下面的代码只包含功能主义者的子集,但它可以进一步扩展。
最大值有一个问题——你不能得到enum class
的最大值(或者我错了吗?)。所以我添加了EnumTraits
。现在,用户需要用等于enum最大值的常量值max
来专门化EnumTraits
,然后才能使用类。
#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
s没有太多功能,而且带有enum class
es的C++11并不能改善这种情况,一些程序员使用封装在类中的静态映射。绝对是本好书。
相关文章:
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将C++中的库和头与MinGW一起使用
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 为什么我不能将 rand() 与数组的大小一起使用?
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 将fold表达式与std::一起用于两个元组
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 将 std::allocate_shared 与多态资源分配器一起使用
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 将 exprtk 与自定义类的对象一起使用
- 将 std::set 与基于键的比较器一起使用
- 将 C++ 类与 Rcpp 一起使用,从 C 或 R 修改它
- 如何将 Eigen::Ref 与 pybind11 一起使用?
- 如何将AERT_Allocate与 std:vector 一起使用
- 如何使我的 sizeof sum 结构与空参数包一起工作
- 将enum类与std::bitset一起使用