[C++] enum class - 안전하고 쓰기 쉬운 enum
C++ 03까지의 enum
은 여러 가지 문제를 가지고 있었다. 그래서 그 문제들을 해결하기 위해 C++ 11은 enum class
라는 것을 새로 만들었다. 이제부터 기존의 enum
에 어떤 문제가 있었고, 이것을 enum class
에서 어떻게 해결하였는지 살펴볼 것이다.
우선 기존의 enum
은 전방 선언할 수 없었다. 그 이유는 enumerator에 어떤 값이 들어있을지 알 수 없으면 그 크기를 정할 수 없기 때문이다. 하지만 enum class
는 underlying type을 명시하지 않으면 int
타입과 같은 크기의 변수로 선언되고, int
값 안에 들어가지 못할 값을 지정하면 컴파일 에러를 발생시킨다.
만약 int
를 벗어난 범위의 값을 사용하고 싶다면, underlying type을 명시해주어야 한다.
기존 enum
의 또 다른 문제는 enumerator의 이름의 범위가 한정되지 않는다는 것이다. 예를 들어 아래와 같은 코드를 보자.
IO 함수의 결과와 Parse 함수의 결과를 enum
으로 표현해 보았다. 하지만 이 코드는 컴파일되지 않는다. IOResult
의 Error
, Ok
가 ParseResult
의 Error
, Ok
와 겹치기 때문이다. 이를 해결하기 위해서는 다음과 같이 enumerator의 이름을 다르게 하거나
아래와 같이 namespace
를 이용해야 했다.
하지만 enum class
는 enumerator의 이름이 enum class
안으로 한정되기 때문에 이런 복잡한 과정이 필요 없이 그저 enum class
를 선언하여 사용하면 된다.
무엇보다 기존 enum
의 가장 큰 문제는 정수형 변수로 암시적으로 변환되는 약 타입(weak type) 변수라는 것이다. 하지만 enum class
는 정수형 변수로 암시적 변환이 되지 않는다. enum class
를 정수형 변수처럼 사용하려고 하면 컴파일 에러를 발생시킨다. 만약 정수형 변수로 사용하고 싶으면 static_cast
를 이용해 명시적으로 캐스팅해서 사용해야 한다.
위에서 설명한 대로 기존의 enum
은 전방 선언할 수 없고, enumerator 이름의 범위가 한정되지 않고, 정수형 변수로 암시적으로 변환되지도 않는다. 사실 enum
의 사용법을 생각해보면 enum class
가 올바른 방식이다. 하지만 C++ 11은 backward compatibility를 위해서 기존의 enum
을 그대로 두고, enum class
를 새로 추가하는 것을 선택했다. 이제는 compatibility를 위해서가 아니면 enum
의 존재는 잊고 대신에 enum class
를 사용하는 것이 좋다.
댓글
댓글 쓰기