본문 바로가기
C++/Effective Modern C++

범위 없는 enum 보다 범위 있는 enum으로

by COCO1337 2020. 7. 2.

범위 없는 enum(unscoped enum)

C++98에서 enum으로 선언된 열거자들은 enum을 포함하는 범위에 속하며, 그 범위에 같은 이름이 있으면 안된다.

(열거자들이 enum의 범위 밖으로 새어나간다)

enum Color { black, white, red };
auto white = false;		// white가 Color의 범위에 속해 있기 때문에 오류

또한 암묵적으로 정수 형식으로 변환된다.

enum Color { black, white, red };
std::vector<std::size_t> primeFactors(std::size_t x);
Color c = red;
...
if (c < 14.5) {
	auto factors = primeFactors(c);		// 컴파일 된다
...
}

 

 

범위 있는 enum(scoped enum), enum class

C++11에서 class를 붙여주는 것으로 열거자들이 enum의 범위 밖으로 새어나가지 않고, 그렇기 때문에 namespace의 오염도 줄여줄 수 있다.

enum class Color { black, white, red };
auto white = false;
Color c = white;		// 이 범위에 white라는 이름의 열거자가 없기 때문에 오류
Color c = Color::white;
auto c = Color::white;

또한 암묵적으로 다른 형식으로 변환되지 않는다.

enum class Color { black, white, red };
std::vector<std::size_t> primeFactors(std::size_t x);
Color c = Color::red;
...
if (c < 14.5) {			// Color와 double 비교 불가
	auto factors = primeFactors(c);	// std::size_t를 기대하는 함수에 Color 전달할 수 없음
...
}

forward declaration이 가능하다

enum Color; 		// 오류
enum class Color;	// 가능

enum State { a = 0, c = 2 };
enum State { a = 0, b = 1, c = 2 };		// 추가 할 경우 관련된 부분을 전부 컴파일 해야 한다

컴파일러들은 주어진 enum의 열거자 값들의 범위를 표현할 수 있는 가장 작은 바탕 형식을 선택하는 경향이 있다. C++98에서는 enum 정의만 지원하고 선언은 허용하지 않기 때문에 실제로 쓰이기 전에 컴파일러가 enum의 형식을 알 수 있게 된다. 범위 있는 enum의 경우 기본 바탕 형식은 int, 또한 사용자가 직접 지정할 수 있기 때문에 컴파일러는 enum의 형식을 알 수 있게 된다.


Conclusion

- C++98 스타일의 enum을 unscoped enum이라 한다.

- 범위 있는 enum의 열거자들은 그 안에서만 보이며, 오직 캐스팅을 통해서만 다른 형식으로 변환된다.

- scoped enum의 기본 형식은 int, unscoped enum의 기본 형식은 없다.

- forward declaration을 위해서는 바탕 형식이 필요하기 때문에 unscoped enum이 forward declaration 하려면 바탕 형식을 지정해야 한다


Reference

Effective Modern C++ 항목 10: 범위 없는 enum보다 범위 있는 enum을 선호하라

반응형

댓글