2012-01-03 3 views
1

다음과 비슷한 중첩 열거 형이 여러 개 있습니다. 나는 isValid() 함수를 enum 정의에 최대한 가깝게 정의하려고합니다. 실제 코드는 여러 수준의 중첩 된 네임 스페이스와 구조체를 사용하여 더욱 자세한 정보를 제공합니다.중첩 열거 형에 대한 C++ 연산

struct S 
{ 
    enum E { V1, V2 }; 
    /* ????? */ bool isValid(E e) { return e==V1 || e==V2; } 
}; 

template <typename Enum> 
bool legalValue(Enum e) 
{ 
    return isValid(e); 
} 

는 글로벌 네임 스페이스에 isValid()을 배치 할 필요없이 코드가 작동 할 수 있습니까?

isValid()이 우수 사례인지 여부에 대해 의견을 말하지 마십시오. 이 질문은 의미있는 방법으로 열거 형 값을 스트리밍 할 수 있도록 operator<<()을 재정의하려는 사람에게도 해당됩니다. 이 경우, operator<<()의 본질이 struct S의 본문에있을 수있는 방법이 있습니까?

+1

여기에 어떤 문제가 있는지 잘 모르겠습니다. 'isValid()'함수를'static'으로 만들고,'legalValue()'함수를'return S :: isValid (e);'함수로 변경하면, 컴파일해야한다고 생각합니다 ... –

+0

아이디어는 'legalValue ()'은 연관된'isValid()'함수가있는'enum'에 대해 작동해야합니다. 'class' 또는'struct'로 중첩 된 enum에는 작동하지 않습니다. – paperjam

+0

구조체 대신 네임 스페이스 안에 열거 형을 넣으십시오. 이렇게하면 ADL이 시작될 것이고 (테스트하지는 않았다), enum이 선언 된 네임 스페이스에 관계없이 isValid를 호출 할 수 있어야한다. – paercebal

답변

4

아니요, 에서 isValid으로 이동해야합니다. 하지만 enum 정의는 그 안에있을 수 있습니다.

struct S 
{ 
    enum E { V1, V2 }; 
}; 

bool isValid(S::E e) { return e == S::V1 || e == S::V2; } 

template <typename Enum> 
bool legalValue(Enum e) 
{ 
    return isValid(e); 
} 
+0

OP의 규정 중 하나는 "전역 네임 스페이스에 isValid()를 넣지 않아도이 코드가 작동하도록 할 수 있습니까?"... –

+0

고맙지 만,이 솔루션 이외의 다른 솔루션이 있는지 묻는 중입니다. – paperjam

+1

@OliCharlesworth : 나는 대답이 '아니오'라고 생각합니다. 나는 표준에서 합창과 절을 인용 할 수는 없지만 대답을 업데이트했습니다. –

3

SS::E에서 찾을 수 없습니다.

이 전체 네임 스페이스의 일부가 아니더라도 isValid을 찾을 수 있지만 그게 무슨 뜻인지는 생각하지 않습니다.

1

이 즉, C++ 2011 표준 C++에 대한 경우, 당신은 중첩 된 열거 선언 전달할 수 : 물론

struct S { enum E: int; }; 

enum S::E: int { V1, V2 }; 
bool isValid(S::E e) { return e == S::V1 || S::V2; } 

, 당신은 또한 중첩에 열거 필요가 없습니다 것을 구조체는 클로징 범위의 오염을 피하기 위해 : 대신 불법 될 자격이 V1 또는 V2를 사용

enum class S { V1, V2 }; 
bool isValid(S e) { return e == S::V1 || S::V2; } 

을 사용하십시오.

1

이들은 기술적 인 부분 일 수 있지만 isValid을 글로벌하게 만드는 또 다른 옵션은 legalValue을 오버로드 (또는 전문화)하는 것입니다.

struct S 
{ 
    enum E { V1, V2 }; 
    static bool isValid(E e) { return e==V1 || e==V2; } 
}; 
bool legalValue(S::E e) { return S::isValid(e); } 

template <typename Enum> 
bool legalValue(Enum e) { return isValid(e); } 

또 다른 옵션은 isValid 글로벌 친구를 만드는 것입니다. 이것과 거의 다른 점은 무료 전역 기능입니다.

struct S 
{ 
    enum E { V1, V2 }; 
    friend bool isValid(E e) { return e==V1 || e==V2; } 
}; 
template <typename Enum> 
bool legalValue(Enum e) { return isValid(e); } 
관련 문제