C++ 11부터는 enum class라는 syntax를 지원한다. 이 enum class는 기존의 enum의 문제점을 보완하고자 나온 syntax이다. enum은 사용자 정의 타입임에도 정수형과 호환이 가능하다. 예를 들어서
enum Color
{
RED,
GREEN,
BLUE
};
int main()
{
int rgb = RED;
}
또한 enum은 정의하면 enum내에서가 아닌 enum이 포함된 스코프 내에서 정의되기 때문에 같은 스코프 내에서 서로 다른 enum 블록에서 정의한다고 하더라도 이름이 겹치면 재정의된 것으로 보고 오류가 난다. 예를 들어서
int main()
{
enum Color
{
RED,
BLUE,
GREEN, // duplicated!
};
enum Color2
{
GREEN, // duplicated!
YELLOW,
WHITE
};
}
이렇게 서로 다른 enum문이라고 하더라도 GREEN이 두번 정의된 것으로 본다.
또한 enum은 사용자 정의 타입을 만든 셈인데, 이렇게 사용자 정의 타입을 만들었는데 정수형과 아무 문제없이 호환된다. Type safe하지 않다는 의미다. 또한 이런 것도 문제없이 컴파일 된다.
enum Color
{
RED,
BLUE,
GREEN,
};
enum Direction
{
LEFT,
RIGHT
};
int main()
{
Color color = RED;
Direction dir = LEFT;
if (color == dir)
{
std::cout << "color is same as direction" << std::endl;
}
}
타입도 다르고 변수에 저장된 내용도 다르지만 비교도 가능하고 심지어 같다고 한다. 이런 이유는 실제로는 그냥 정수형 상수로 지정되어 있기 때문이다. 참고로 enum은 다음과 같이 정수를 할당해줄 수 있다.
enum Direction
{
LEFT,
RIGHT
};
enum Color
{
RED,
BLUE = 30,
GREEN,
};
int main()
{
Direction Left = LEFT;
Direction Right = RIGHT;
std::cout<<"LEFT: "<<Left<<std::endl; // 0
std::cout<<"RIGHT: "<<Right<<std::endl; // 1
Color Red = RED;
Color Blue = BLUE;
Color Green = GREEN;
std::cout<<"RED: "<<Red<<std::endl; // 0
std::cout<<"BLUE: "<<Blue<<std::endl; // 30
std::cout<<"GREEN: "<<Green<<std::endl; // 31
}
아무런 상수를 할당하지 않으면 0부터 시작하고, 할당한다면 할당한 수부터는 1씩 증가한다.
다시 enum의 문제점으로 돌아와보자. enum은 위에서 언급한 문제들 때문에 C++ 11부터는 enum class를 지원하고 enum말고 enum class를 사용하도록 권고한다. enum class은 다음 코드처럼 쓸 수 있다.
enum class Job
{
Knight,
Magician,
Archer
};
enum class Coffee
{
Americano,
Latte,
Mocha,
};
enum class Job2
{
Archer,
Warrior
};
int main()
{
// Job job = Archer; // Not allowed
Job job2 = Job::Magician;
Coffee coffee = Coffee::Mocha;
//if (job2 == coffee) Not allowed
//{
// std::cout << "Job is same as Coffee" << std::endl;
//}
}
먼저 눈에 띄는 점은 Job에도 Archer가 있고 Job2에도 Archer가 있는데 문제가 없다. 이것은 두개가 서로 별개의 enum 스코프 내에서 정의된 것이기 때문이다. 마치 서로 다른 함수 내에서 같은 이름의 지역변수를 선언하는건 문제 없듯이. 그리고 이전 enum과 달리 enum class는 말 그대로 class이기 때문에 scope 연산자(::)를 사용해야 한다. 마지막으로 enum에서 허용됐던 서로 다른 타입끼리의 비교가 허용되지 않는다.
Reference
https://unikys.tistory.com/376
https://boycoding.tistory.com/180
'공부 > C || C++' 카테고리의 다른 글
C++11 chrono (0) | 2021.07.16 |
---|---|
C++ 11 default, delete 키워드 (0) | 2021.07.15 |
char*를 cout으로 출력할 경우 주소가 올바르게 나오지 않는 경우 (0) | 2021.07.09 |
C++ 전처리기(preprocessor) (0) | 2021.07.08 |
C+ 11 스마트 포인터(unique_ptr, shared_ptr, weak_ptr) (0) | 2021.07.07 |