문제

나는 Enum의 작동 방식을 파악하기 위해 약간의 C ++ 표준을 읽으려고 노력했습니다. 실제로 내가 원래 생각한 것보다 더 많은 것이 있습니다.

범위를 둔 열거의 경우 기본 유형이 int 열거 기반 절로 달리 명시되지 않는 한 (모든 적분 유형 일 수 있음).

enum class color { red, green, blue};  // these are int

공제되지 않은 열거의 경우, 기본 유형이 작동하는 필수 유형이 될 수 있으며 필요하지 않은 경우 int보다 크지 않을 것 같습니다.

enum color { red, green, blue};  // underlying type may vary

기본 유형의 미군 열거는 표준화되지 않기 때문에, 직렬화 인스턴스를 다루는 가장 좋은 방법은 무엇입니까? 지금까지 나는 변환했다 int 글을 쓸 때, int 그리고 내 enum 읽을 때 스위치에서 변수가 있지만 약간 어리석은 것 같습니다. 더 좋은 방법이 있습니까?

enum color { red, green, blue };
color c = red;
// to serialize
archive << (int)c;
// to deserialize
int i;
archive >> i;
switch(i) {
  case 0: c = red; break;
  case 1: c = green; break;
  case 2: c = blue; break;
}
도움이 되었습니까?

해결책

C ++ 0X 물건을 읽지 않았으므로 댓글을 달 수 없었습니다.

직렬화에 관해서는 열거를 다시 읽을 때 스위치가 필요하지 않습니다.

그러나 나는 스트림에 쓸 때 캐스트하지 않습니다. 이것은 종종 연산자를 쓰는 것을 좋아하기 때문에 << 열거적인 <<이 쓰여진 나쁜 값을 잡을 수 있거나 대신 문자열을 작성하기로 결정할 수 있기 때문입니다.

enum color { red, green, blue };
color c = red;

// to serialize
archive << c;    // Removed cast

// to deserialize
int i;
archive >> i;
c = (color)i;    // Removed switch

다른 팁

열거적인 클래스 a C ++ 0x 기능, C ++ 03에는 존재하지 않습니다.

표준 C ++에서 열거는 유형-안전하지 않습니다. 열거 유형이 뚜렷한 경우에도 효과적으로 정수입니다. 이를 통해 상이한 열거 유형의 두 개의 열거 값을 비교할 수 있습니다. C ++ 03이 제공하는 유일한 안전성은 정수 또는 하나의 열거 유형의 값이 암시 적으로 다른 열거 유형으로 변환하지 않는다는 것입니다. 또한, 정수의 크기 인 기본 적분 유형은 명시 적으로 지정할 수 없습니다. 구현이 정의되었습니다. 마지막으로, 열거 값은 둘러싸인 범위로 범위를 지정합니다. 따라서 두 개의 개별 열거가 일치하는 멤버 이름을 갖는 것은 불가능합니다. C ++ 0X는 이러한 문제가없는 특별 열거의 분류를 허용합니다. 이것은 열거 클래스 선언을 사용하여 표현됩니다

예제 (Wikipedia 기사) :

enum Enum1;                   //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int;    //Legal in C++0x.
enum class Enum3;             //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short;  //Illegal in C++0x, because Enum2 was previously declared with a different type.

직렬화 부품 (원래 질문의 일부가 아니라고 생각하는)의 경우, 이름은 일반적으로 정수 값보다 더 안정적이므로 열거 항목을 문자열로 해당 (및 뒤로)로 변환하는 도우미 클래스를 만드는 것을 선호합니다. 열거 된 항목은 코드 동작을 변경하지 않고 다시 주문할 수 있으므로 (때로는)를 나타냅니다.

나는 내 옛날이 너무 지저분했기 때문에 새로운 대답을 만들기로 결정했습니다. 어쨌든 C ++ 11에 대해 무언가를 말하고 싶어요.

std::underlying_type_t<E>

그리고 관심을 끌기 위해 과부하 분해능 아이디어. 그러나 @lothar가 제안한 바와 같이 이름을 사용하여 열거를 저장하십시오.

과부하 분해능은 열거에서 서명되지 않은 int, 길고 서명되지 않은 길고의 첫 번째 홍보가 기본 유형의 모든 값을 나타낼 수 있다는 사실에서 비롯됩니다. 다른 정수 유형으로의 변환은 순위가 낮고 과부하 분해능은 선호하지 않습니다.

char (& f(int) )[1];
char (& f(unsigned int) )[2];

char (& f(long) )[3];
char (& f(unsigned long) )[4];

char const* names[] = { 
    "int", "unsigned int", 
    "long", "unsigned long"
};

enum a { A = INT_MIN };
enum b { B = UINT_MAX };
enum c { C = LONG_MIN };
enum d { D = ULONG_MAX };

template<typename T> void print_underlying() {
    std::cout << names[sizeof(f(T()))-1] << std::endl;
}

int main() { 
    print_underlying<a>();
    print_underlying<b>();
    print_underlying<c>();
    print_underlying<d>();
}

그리고 여기에는 이것을 인쇄합니다.

int
unsigned int
int
unsigned int

이 직렬화 문제에 특히 관심이 없습니다 (직렬화 된 데이터의 크기는 일정한 폭이 아니기 때문에 열거와 기본 유형이 변경 될 때 문제가 발생할 수 있지만 일반적으로 유형 저장을 파악하는 것이 흥미 롭습니다. 열거 전체. 건배!

#include <type_traits>

enum a { bla1, bla2 };
typedef typename std::underlying_type<a>::type underlying_type;

if (std::is_same<underlying_type, int>::value)
  std::cout << "It's an int!" << endl;
else if (std::is_same<underlying_type, unsigned int>::value)
  std::cout << "It's an uint!" << endl;

에 관해서 enum class color:이 C ++/CLI (C ++ .NET) 또는 향후 C ++ 0X 코드입니까?

직렬화를 위해 sizeof(color) 복사 할 바이트 수를 아는 것.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top