eidolon 이 현재 허용하는 답변을 찾습니다 너무 위험하다는 것을 습니다. 컴파일러의 옵티마이 저는 열거 형에서 가능한 값에 대한 가정을 할 수 있으며 잘못된 값으로 가비지를 다시 가져올 수 있습니다. 그리고 보통 아무도 가능한 모든 순열을 플래그 열거 형으로 정의하고 싶지 않습니다.
Brian R. Bondy가 아래에 언급했듯이 C ++ 11 (모든 사람이 좋아야 함)을 사용하는 경우 이제 다음을 사용하여보다 쉽게 수행 할 수 있습니다 enum class
.
enum class ObjectType : uint32_t
{
ANIMAL = (1 << 0),
VEGETABLE = (1 << 1),
MINERAL = (1 << 2)
};
constexpr enum ObjectType operator |( const enum ObjectType selfValue, const enum ObjectType inValue )
{
return (enum ObjectType)(uint32_t(selfValue) | uint32_t(inValue));
}
// ... add more operators here.
이렇게하면 열거 형의 유형을 지정하여 안정적인 크기와 값 범위를 보장하고을 사용하여 열거 형을 int 등으로 자동 다운 캐스팅 enum class
하는 constexpr
것을 방지하고 연산자의 코드가 인라인되어 정규 숫자만큼 빠릅니다.
11 세 이전의 C ++ 방언을 고수 한 사람들
C ++ 11을 지원하지 않는 컴파일러가 붙어 있다면 클래스에 int 유형을 래핑하여 비트 연산자와 해당 열거 형의 유형 만 사용하여 값을 설정할 수 있습니다.
template<class ENUM,class UNDERLYING=typename std::underlying_type<ENUM>::type>
class SafeEnum
{
public:
SafeEnum() : mFlags(0) {}
SafeEnum( ENUM singleFlag ) : mFlags(singleFlag) {}
SafeEnum( const SafeEnum& original ) : mFlags(original.mFlags) {}
SafeEnum& operator |=( ENUM addValue ) { mFlags |= addValue; return *this; }
SafeEnum operator |( ENUM addValue ) { SafeEnum result(*this); result |= addValue; return result; }
SafeEnum& operator &=( ENUM maskValue ) { mFlags &= maskValue; return *this; }
SafeEnum operator &( ENUM maskValue ) { SafeEnum result(*this); result &= maskValue; return result; }
SafeEnum operator ~() { SafeEnum result(*this); result.mFlags = ~result.mFlags; return result; }
explicit operator bool() { return mFlags != 0; }
protected:
UNDERLYING mFlags;
};
이것을 일반적인 enum + typedef처럼 정의 할 수 있습니다 :
enum TFlags_
{
EFlagsNone = 0,
EFlagOne = (1 << 0),
EFlagTwo = (1 << 1),
EFlagThree = (1 << 2),
EFlagFour = (1 << 3)
};
typedef SafeEnum<enum TFlags_> TFlags;
사용법도 비슷합니다.
TFlags myFlags;
myFlags |= EFlagTwo;
myFlags |= EFlagThree;
if( myFlags & EFlagTwo )
std::cout << "flag 2 is set" << std::endl;
if( (myFlags & EFlagFour) == EFlagsNone )
std::cout << "flag 4 is not set" << std::endl;
그리고 enum foo : type
두 번째 템플릿 매개 변수를 사용하여 이진 안정 열거 형 (C ++ 11과 같은)의 기본 유형을 재정의 할 수도 있습니다 typedef SafeEnum<enum TFlags_,uint8_t> TFlags;
.
플래그를 작성할 때 플래그 집합이 0 또는 1로 축소 될 수 있기 때문에 int 변환이 발생하지 않도록 operator bool
C ++ 11의 explicit
키워드로 재정의를 표시 했습니다. C ++ 11을 사용할 수 없다면, 오버로드를 남겨두고 예제 사용법에서 첫 번째 조건을로 다시 작성하십시오 (myFlags & EFlagTwo) == EFlagTwo
.
[Flags]
[Flags] enum class FlagBits{ Ready = 1, ReadMode = 2, WriteMode = 4, EOF = 8, Disabled = 16};