使用枚举类的C ++ 11标准一致位掩码 [英] C++11 standard conformant bitmasks using enum class
问题描述
您可以使用enum类实现标准符合(如n3242草案的17.5.2.1.3中所述)类型的安全位掩码吗?按照我的阅读方式,如果类型T支持|,&,^,〜,| =,& =和^ =运算符,则它是位掩码,并且进一步可以执行if(l& r),其中l和r属于T类型。列表中缺少运算符!=和==,并且为了允许排序可能还想重载<。
Can you implement standard conformant (as described in 17.5.2.1.3 of the n3242 draft) type safe bitmasks using enum class? The way I read it, a type T is a bitmask if it supports the |,&,^,~,|=,&= and ^= operators and further you can do if(l&r) where l and r are of type T. Missing from the list are the operator != and == and to allow sorting one probably also wants to overload <.
让运算符起作用只是令人讨厌的样板代码,但我看不到if(l& r)怎么办。至少以下代码不能与GCC一起编译(由于极其危险,因为它允许将错误的隐式转换为int):
Getting the operators to works is just annoying boilerplate code but I do not see how to do if(l&r). At least the following does not compile with GCC (besides being extremely dangerous as it allows an erroneous implicit conversion to int):
enum class Foo{
operator bool(){
return (unsigned)*this;
}
};
编辑:我现在确定枚举类不能有成员。
I now know for certain that enum classes can not have members. The actual question how to do if(l&r) remains though.
推荐答案
我认为您可以...
您必须添加用于位屏蔽事件的运算符。我在这里没有这样做,但是您可以轻松地重载任何关系运算符。
I think you can... You'll have to add operators for bitmasky things. I didn't do it here but you could easily overload any relational operator.
/**
*
*/
// 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;
}
这篇关于使用枚举类的C ++ 11标准一致位掩码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!