enum X : int
(C 번호) 또는 enum class X : int
(C ++ 11)의 숨겨진 내부 필드 갖는 타입 int
의 값을 보유 할 수있다. 또한 많은 사전 정의 된 상수가 X
열거 형에 정의되어 있습니다. 열거 형을 정수 값으로 캐스트 할 수 있으며 그 반대도 가능합니다. 이것은 C #과 C ++ 11 모두에 해당됩니다.
C # 열거 형은 Microsoft의 권장 사항에 따라 개별 값을 보유 할뿐만 아니라 플래그의 비트 조합을 보유하는 데 사용됩니다 . 이러한 열거 형은 (보통은 아니지만 반드시) [Flags]
속성으로 장식됩니다 . 개발자의 삶을 쉽게하기 위해 비트 연산자 (OR, AND 등 ...)가 오버로드되어 다음과 같이 쉽게 수행 할 수 있습니다 (C #).
void M(NumericType flags);
M(NumericType.Sign | NumericType.ZeroPadding);
저는 숙련 된 C # 개발자이지만 지금은 며칠 동안 만 C ++을 프로그래밍하고 있으며 C ++ 규칙에 대해서는 알려져 있지 않습니다. C #에서와 똑같은 방식으로 C ++ 11 열거 형을 사용하려고합니다. C ++ 11에서는 범위가 지정된 열거 형의 비트 연산자가 오버로드되지 않으므로 오버 로드하고 싶었습니다 .
이것은 논쟁을 불러 일으켰으며, 의견은 세 가지 옵션 사이에서 다양하게 보인다.
열거 형의 변수는 C #과 유사한 비트 필드를 유지하는 데 사용됩니다.
void M(NumericType flags); // With operator overloading: M(NumericType::Sign | NumericType::ZeroPadding); // Without operator overloading: M(static_cast<NumericType>(static_cast<int>(NumericType::Sign) | static_cast<int>(NumericType::ZeroPadding)));
그러나 이것은 C ++ 11의 범위가 지정된 열거 형의 강력한 형식의 열거 형 철학에 맞지 않습니다.
열거 형의 비트 조합을 저장하려면 일반 정수를 사용하십시오.
void M(int flags); M(static_cast<int>(NumericType::Sign) | static_cast<int>(NumericType::ZeroPadding));
그러나 이것은 모든 것을로 줄여서
int
메소드에 어떤 유형을 넣어야할지 전혀 알지 못합니다.연산자를 오버로드하고 숨겨진 정수 필드에 비트 단위 플래그를 보유하는 별도의 클래스를 작성하십시오.
class NumericTypeFlags { unsigned flags_; public: NumericTypeFlags () : flags_(0) {} NumericTypeFlags (NumericType t) : flags_(static_cast<unsigned>(t)) {} //...define BITWISE test/set operations }; void M(NumericTypeFlags flags); M(NumericType::Sign | NumericType::ZeroPadding);
( 전체 코드 에 의해 user315052 )
그러나 IntelliSense 또는 가능한 값을 알려주는 지원이 없습니다.
나는 이것이 주관적인 질문 이라는 것을 알고 있지만, 어떤 접근법을 사용해야합니까? C ++에서 가장 널리 인식되는 접근법은 무엇입니까? 비트 필드와 처리 할 때 당신은 어떤 방법을 사용합니까 왜 ?
물론 세 가지 접근 방식이 모두 효과가 있기 때문에 저는 개인적으로 선호되는 것이 아니라 사실적이고 기술적 인 이유, 일반적으로 받아 들여지는 규칙을 찾고 있습니다.
예를 들어, C # 배경으로 인해 C ++에서 접근법 1을 사용하는 경향이 있습니다. 이것은 내 개발 환경이 가능한 값을 암시 할 수 있다는 추가 이점을 가지고 있으며 과부하 된 열거 형 연산자를 사용하면 작성하고 이해하기 쉽고 깨끗합니다. 그리고 메소드 서명은 어떤 종류의 가치를 기대하는지 명확하게 보여줍니다. 그러나 여기에있는 대부분의 사람들 은 나에게 동의하지 않을 것입니다. 아마 그럴만한 이유가 있습니다.
enum E { A = 1, B = 2, C = 4, };
경우 범위는 0..7
(3 비트)이므로 C ++ 표준은 # 1이 항상 실행 가능한 옵션임을 명시 적으로 보장합니다. (특히 달리 지정하지 않는 한 enum class
기본값은 기본적으로 enum class : int
고정 된 기본 유형을 갖습니다.])