B.S*_*.S. 30 c++ bitmask bit-fields c++11 enum-class
您可以使用枚举类实现标准符合(如n3242草案的17.5.2.1.3所述)类型安全位掩码吗?我读它的方式,类型T是一个位掩码,如果它支持|,&,^,〜,| =,&=和^ =运算符,你还可以做if(l&r)其中l和r是T类型.列表中缺少的是运算符!=和==并允许排序一个也可能想要重载<.
让操作员工作只是烦人的样板代码,但我不知道如何(l&r).至少下面的代码不能用GCC编译(除了极其危险,因为它允许错误的隐式转换为int):
enum class Foo{
operator bool(){
return (unsigned)*this;
}
};
Run Code Online (Sandbox Code Playgroud)
编辑:我现在肯定知道枚举类不能有成员.实际问题如果(l&r)仍然存在.
ems*_*msr 27
我想你可以......你必须为bitmasky事情添加运算符.我没有在这里做,但你可以轻松地重载任何关系运算符.
/**
*
*/
// NOTE: I changed to a more descriptive and consistent name
// This needs to be a real bitmask type.
enum class file_permissions : int
{
no_perms = 0,
owner_read = 0400,
owner_write = 0200,
owner_exe = 0100,
owner_all = 0700,
group_read = 040,
group_write = 020,
group_exe = 010,
group_all = 070,
others_read = 04,
others_write = 02,
others_exe = 01,
others_all = 07,
all_all = owner_all | group_all | others_all, // 0777
set_uid_on_exe = 04000,
set_gid_on_exe = 02000,
sticky_bit = 01000,
perms_mask = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit, // 07777
perms_not_known = 0xffff,
add_perms = 0x1000,
remove_perms = 0x2000,
symlink_perms = 0x4000
};
inline constexpr file_permissions
operator&(file_permissions x, file_permissions y)
{
return static_cast<file_permissions>
(static_cast<int>(x) & static_cast<int>(y));
}
inline constexpr file_permissions
operator|(file_permissions x, file_permissions y)
{
return static_cast<file_permissions>
(static_cast<int>(x) | static_cast<int>(y));
}
inline constexpr file_permissions
operator^(file_permissions x, file_permissions y)
{
return static_cast<file_permissions>
(static_cast<int>(x) ^ static_cast<int>(y));
}
inline constexpr file_permissions
operator~(file_permissions x)
{
return static_cast<file_permissions>(~static_cast<int>(x));
}
inline file_permissions &
operator&=(file_permissions & x, file_permissions y)
{
x = x & y;
return x;
}
inline file_permissions &
operator|=(file_permissions & x, file_permissions y)
{
x = x | y;
return x;
}
inline file_permissions &
operator^=(file_permissions & x, file_permissions y)
{
x = x ^ y;
return x;
}
Run Code Online (Sandbox Code Playgroud)
我不完全确定你的接受标准是什么,但你可以operator &通过适当的转换返回一个包装类,并且explicit operator bool:
#include <type_traits>
template<typename T> using Underlying = typename std::underlying_type<T>::type;
template<typename T> constexpr Underlying<T>
underlying(T t) { return Underlying<T>(t); }
template<typename T> struct TruthValue {
T t;
constexpr TruthValue(T t): t(t) { }
constexpr operator T() const { return t; }
constexpr explicit operator bool() const { return underlying(t); }
};
enum class Color { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff };
constexpr TruthValue<Color>
operator&(Color l, Color r) { return Color(underlying(l) & underlying(r)); }
Run Code Online (Sandbox Code Playgroud)
当然,所有其他运营商都可以继续返回Color:
constexpr Color
operator|(Color l, Color r) { return Color(underlying(l) | underlying(r)); }
constexpr Color operator~(Color c) { return Color(~underlying(c)); }
int main() {
constexpr Color YELLOW = Color::RED | Color::GREEN;
constexpr Color WHITE = Color::RED | Color::GREEN | Color::BLUE;
static_assert(YELLOW == (WHITE & ~Color::BLUE), "color subtraction");
return (YELLOW & Color::BLUE) ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)
作用域枚举(使用 或 创建的枚举enum class)enum struct不是类。它们不能有成员函数,它们只是提供封闭的枚举器(在命名空间级别不可见)。