2010-08-14 4 views
15

C++에서 템플릿 (형식) 인수로 열거 형을 사용하는 데 제한/문제가 있습니까?C++에서 템플릿 형식 인수로 enum을 사용

예 :

enum MyEnum 
{ 
    A, B, C, D, E 
}; 

template <typename _t> 
class MyTemplate 
{ 
public: 
    _t value; 

    void func(const _t& param) { /* .... */ } 
}; 

// .... 

MyTemplate<MyEnum> MyInstance; 

는 Win32에서 VS 2008 (SP1)을 통해 ++/86를 MSVC를 사용하여 내 실제 문제는 클래스로 열거를 사용와 관련하여 (컴파일러에 의해보고 된 = 오류) 여러 컴파일 오류가 템플릿 인수. 불행히도 내 프로젝트 불행히도 (당신은 디자인 오류로 간주 할 수 있습니다 : P), 이러한 오류를 제기 템플릿 클래스 파생, 중첩 및 열거 템플릿 매개 변수를 사용하여 클래스에 대한 전문도 복잡 해졌다.

빌드를 시도하면 컴파일러는 주석이있는 행에 "C2059 : syntax error : 'public'"과 같은 여러 가지 잘못된/쓸모없는 오류를보고합니다. 그 중 많은 것들은 예에서와 비슷한 방법으로 const _t & 매개 변수를 대체하여 해결할 수 있습니다 (매개 변수 복사). 그러나이 오류를 모두 해결할 수 없으며이 도움이되는 이유도 없습니다. ". ** 위의 간단한 예제는 w/o 오류를 컴파일합니다.

열거 형 대신 int를 사용하여 프로젝트에서 w/o 오류를 컴파일합니다.

미리 알려 주시면 감사하겠습니다.


편집 : 결국

, 나는 심각하게 컴파일러의 버그로 이것을 고려하십시오. 단순화 된 코드로 오류를 재현하려 할 때 매우 결정적이지 않은 모든 "빌드"의 50 % 만 가져 왔습니다.
예. 컴파일을 시도하고이 오류를보고했습니다. 다시 빌드 - 변경하지 마십시오. 주석을 삭제하고 빌드 - 변경하지 않았습니다. Rebuild - 그리고 나서 : no errors, 괜찮아요.

나는 이미 몇 가지 컴파일러 버그 (20k 줄의 코드 내에서 2 ~ 3 개)를 만났습니다. 그러나 이건 저에게 매우 이상하게 보입니다.
이 컴파일러 인 경우 인 경우 어떤 방법을 제안합니까?

+3

"빌드를 시도하면 컴파일러에서 여러 가지 잘못된/쓸모없는 오류를보고합니다."이러한 "쓸모없는"오류는 종종 /와 어디서 잘못되었는지에 대한 매우 자세한 설명이 포함되어 있습니다. "오류 목록"대신 컴파일러 출력을 읽으십시오. – SigTerm

+0

힌트를 보내 주셔서 감사합니다. 나는 항상 그렇게한다 ^^ 오류 : C2059 오류 : 구문 오류 : 'public'오류 C2143 : 구문 오류 : '>'before ';' 오류 C2143 : 구문 오류 : 누락 된 ';' '}'치명적인 오류 C1004 : 예기치 않은 파일 끝 (그리고이 질문과 관련없는 다른 오류가 있음)이 모두는 enum을 사용할 때만 나타나며 int를 사용할 때 사라진다. – dyp

+0

이것은 나에게 완벽하게 들뜬다. . 이것은 컴파일러 오류 또는 오류 중 하나이며 추측 할 경우 99.9 %의 베팅은 사용자임을 나타냅니다. 하지만 게시 한 스 니펫에는 아무런 문제가 없습니다. 자체적으로 완료되는 작은 샘플과 작성한 정확한 컴파일러 오류를 게시하십시오. – Omnifarious

답변

4

원래의 질문을 참조 :

are there any restrictions/problems using an enum as template (type) argument in C++?

나는 아무것도 발견하지 않았다 - 나는 어떤 있다고 생각하지 않습니다. Potatoswatter가 말했듯이,이 기법은 자주 사용되지 않기 때문에 나쁜 아이디어로 드러날 수 있습니다. 따라서 Potatoswatter가 말했듯이 이와 관련된 컴파일러 버그가 몇 개있을 수 있습니다.

enum MyEnum : int 
{ 
    A, B, C, D 
}; 

template <typename _t> class MyTemplate 
{ 
public: 
    void print() 
    { 
     cout << "not using any specialisation" << endl; 
    } 
}; 
    template <> class MyTemplate <MyEnum> 
    { 
    public: 
     void print() 
     { 
      cout << "MyEnum specialisation" << endl; 
     } 
    }; 
    template<> class MyTemplate <int> 
    { 
    public: 
     void print() 
     { 
      cout << "int specialisation" << endl; 
     } 
    }; 

template <typename _t> void print(_t param) 
{ 
    MyTemplate<_t> m; 
    m.print(); 
} 


int main() 
{ 
    print(A); 
    print(5); 

    return 0; 
} 

출력은 다음과 같습니다 :
다음과 같은 예를 생각해 다음의 간단한 예를 들어

MyEnum specialisation
int specialisation

모든 작동 및 예상대로 및 열거 템플릿 형식과 다른 형식으로 완벽하게 작동 인수 (= 나는 문제에 대한 어떤 이유도 보이지 않는다).

원래이 질문에 의미가 무엇인지 보여주기 위해 예제를 소개했습니다 (템플릿 유형 인수로 열거, 멤버 또는 메소드 인수 유형으로 가능한 사용법 표시 등). 약간의 배경을 제공하려면 내가 질문을 던졌습니다. ("int에 문제가 있습니까?"라는 질문에) 실제 프로젝트를 컴파일하는 이상한 문제를 언급했습니다.
죄송합니다. 그 자체로 완성 된 코드 조각을 추출 할 수는 없지만 최소한 2k 줄의 코드가 4 개의 파일로 분리되어 있습니다. "구문 오류 : 'public'"및 프로젝트를 컴파일 할 때 다른 구문 오류가 발생했으며 특정 상황 (주석을 삭제하거나 중간 파일을 삭제)에서 나타나거나 사라졌습니다. 불행히도 재 구축은 원본 프로젝트에서 도움이되지 않습니다. 원래는 enum 유형의 전문화를 int로 대체해야했습니다.

여러분의 힌트와 조언에 감사드립니다. 근본적인 문제는 저에게 컴파일러 버그 인 것처럼 보입니다. 대답은 단지 인 것 같습니다. "아니오 - 템플릿 유형 인수로 열거 형을 사용하는 제한이 없습니다". 불편을 드려 죄송합니다.

0

MSVC는 이상하게도 enum (value) 템플릿 매개 변수를 처리합니다. 열거 형을 int으로 부적절하게 승격 시켰으며 연산자가 제대로 정의되지 않았습니다. enum 유형의 템플릿 엔진을 실제로 테스트하지는 않는 것 같습니다.

컴파일러 버그를 증명하는 것은 간단합니다. 유효한 코드를 입력하고 컴파일이 성공했는지 확인합니다. 귀하의 예는 분명하게 준수하므로 문제 (또는 실수는 어쨌든)는 그들의 것입니다.

편집는 : 더 정밀한 점검에 당신은 예 하지이 버그를 재현한다는 것을 말한다. 우리와 다른 누구도 당신이 그와 같은 모범을 보일 때까지 당신을 도울 수 없습니다.

+0

컴파일러에는 버그가 두 가지 방법으로 만 발생한다는 것을 증명할 수 있습니다. a) 관련 표준 에 대해 유효성을 검사합니다. b) 설명서를 읽고 알려진 문제점/결함인지 확인합니다. – Chubsdad

+0

OP는 ' enum * value *를 템플릿 매개 변수로 제공합니다. enum * type *이 매개 변수입니다. –

7

예. 제한 사항이 있습니다. 예를 들어, C++ 03 14.3.1[temp.arg.type]/2

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

에 따라 템플릿 인수로 익명 열거를 사용할 수 없습니다 그래서 다음 코드는 C++ 03에 유효하지 않습니다

template <typename T> 
void f(T) {} 

enum {A}; 

int main() { 
    f(A); 
} 

이 유효 C++ 11에서.

관련 문제