범위 없는 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을 선호하라
'C++ > Effective Modern C++' 카테고리의 다른 글
재정의 함수들은 override로 (0) | 2020.07.05 |
---|---|
정의되지 않은 비공개 함수보다는 삭제된 함수를 (0) | 2020.07.03 |
typedef보다 별칭 선언 (0) | 2020.07.01 |
0과 NULL 보다 nullptr (0) | 2020.06.30 |
객체 생성시 괄호와 중괄호의 구분 (0) | 2020.06.29 |
댓글