enum class를 자유롭게 사용해보자
enum class
enum은 원리 타입을 엄격하게 따지지 않는다. 참고로 타입을 엄격히 따지는 것을 스트롱 타입 (strong type) 이라 하고 타입에 안전하다고 표현한다. enum 타입은 항상 정수로 해석하기 때문에 선언한 형태에 관계없이 모든 enum 타입을 서로 비교할 수 없다.타입을 엄격하게 적용하고 싶다면 enum class를 사용한다. 다음과 같이 정의할 수 있다.
enum class PieceType
{
King = 1;
Queen,
Rook = 10,
Pawn
};
PieceType piece = PieceType::King;
if(PieceType::Quene == 2) { ... }
if(static_cast<int>(PieceType::Quene) == 2) { ... }
enum class도 메서드를 가질 수 있는가?
enum class는 메서드를 가질 수 없다. 하지만 일반 class를 이용하여 기능을 구현 할 수 있다. 아래 예를 확인해보자#define SWITCHEN
class Mode
{
public:
enum Value : uint8_t
{
sleep,
idle,
overrun,
error
};
Mode() = default;
constexpr Mode(Value value) : _value(value) {}
#ifdef SWITCHEN // Enable switch(Mode)
constexpr operator Value() const
{
return _value;
}
explicit operator bool() const = delete;
#else
constexpr bool operator==(Mode mode) const
{
return _value == mode._value;
}
constexpr bool operator!=(Mode mode) const
{
return _value != mode._value;
}
#endif
constexpr bool IsError() const
{
return _value == Value::error;
}
private:
Value _value;
};
int main(int argc, char *argv[])
{
Mode mode = Mode::idle;
switch (mode)
{
case Mode::error:
break;
case Mode::sleep:
break;
case Mode::idle:
break;
case Mode::overrun:
break;
}
return -1;
}
Mode mode = 1;
Mode mode("sleep");
mode.toString();
etc.
explicit 키워드는 자신이 원하지 않는 형변환이 일어나지 않도록 제한하는 키워드이다.constexpr 키워드는 컴파일 시간 상수를 만든다. 컴파일 시간에 결정되는 상수 값으로만 초기화 할 수 있다.
- const와 constexpr의 주요 차이점은 const 변수의 초기화를 런타임까지 지연시킬 수 있는 반면, constexpr 변수는 반드시 컴파일 타임에 초기화가 되어 있어야 한다.
- 초기화가 안 되었거나, 상수가 아닌 값으로 초기화 시도시 컴파일이 되지 않는다.
- 함수에서 사용할 때는 inline을 암시한다. 즉, 컴파일 타임에 평가하기 때문이며, inline함수들과 같이 컴파일된다.
참고
- 전문가를 위한 C++
- Can a enum class have methods?