2013-03-18 2 views
2

다음 스위치는 enum 클래스의 모든 항목을 다루고 있기 때문에 기본 사례를 컴파일하는 이유는 무엇입니까? 처음에는 이것이 강한 이유가 있다고 생각했을 것입니다. enum class.enum 클래스의 모든 항목을 전환 할 때 기본 사례 컴파일

나는 내가 모든 경우를 포함 것을 알면서도 기본 싶은 이유에 : 내 미래의 부주의 다움에 대한이 안전 가드 나 (그리고 다른 동료의)

enum class E { 
    a, 
    b 
}; 

int main() 
{ 
    E c = E::b; 
    switch (c) { 
     case E::a: 
     case E::b: 
      std::cout << "pass" << std::endl; 
      break; 
     default: 
      static_assert(false, "This explodes!"); 
    }  
} 

Proof

+0

'static_assert'는 조건을 검사하고 다음과 같은 조건을 검사합니다. 기본 유형에 맞는 값으로 제한됩니다. 의존성이없고 거짓으로 평가되는 경우 파싱되는 즉시 실행됩니다. – Xeo

+0

일부 컴파일러 (GCC)는 conf 열거의 모든 값에 대해 절을 지정하지 않은 기본 절이없는 switch 문이있는 경우 경고 및/또는 오류가 발생하지 않도록합니다. 이것은 미래의 개발자가 상응하는 'case'절을 추가하지 않고 'E'에 값을 추가하는 것을 막을 수 있습니다. 그것이 'c'가 'E'에서 열거 형 중 하나가 아닌 값을 갖는 경우를 포함하지 않는다고 인정합니다. –

답변

3

누군가가 잘못된 값을 열거 형에 던 졌는지 여부를 컴파일이 알 수 없기 때문에. 고려 : 당신이 명시 적으로 컴파일러를 말하고있다으로

E c = static_cast<E>(42); 

캐스트는 경고 (또는 오류)없이 컴파일 "내가 뭘하는지 알고 값을 확인하지 않습니다." 실제로 이것은 슬프게도 생각보다 자주 발생합니다. :(

또한, 모든 코드는 나중에로 도달 할 수없는 제거 된 경우에도 유효합니다. static_assert(false,...)는, 컴파일시에 실행시에 무슨 일이 일어날 지 독립적으로 실행됩니다.

+0

그건 잘못된 값이 아니에요. 이런 종류의 것은 명시 적으로 열거 형으로 허용되며, 종종 매우 유용합니다. –

+0

@PeteBecker : 결합 할 수있는 enum 모델 플래그 또는 이와 비슷한 플래그가 있다면? 이 경우 사실, 기술적으로 허용됩니다. 나는 (분명히?) 열거 된 값 'a'와'b' 만 유효하기를 원하는 OPs 유스 케이스를 가리 키기 위해 * 불법 *을 사용하고있었습니다. 그래서 불법적 인 것은 기술적 인 것이 아닌 의도 된 의미 적 레벨을 의미합니다. –

1

열거 형은 아니다 예를 들어 :

enum flags { 
    first = 0x01, 
    second = 0x02, 
    third = 0x04, 
    fourth = 0x08 
}; 

flags operator | (flags f0, flags f1) { 
    return flags((int)f0 | (int)f1); 
} 

flags f = first | second; // okay; f holds 0x03 
+2

질문 제목은 C++ 11'enum class'; 코드를 수정하십시오. – dyomas

관련 문제