2009-07-01 5 views
9

왜 사용 선언이 종속 기본 클래스에서 형식 이름을 가져 오는 데 효과적이지 않은지 아는 사람 있습니까? 그것들은 멤버 변수와 함수를 다루지 만 적어도 GCC 4.3에서는 타입에 대해 무시되는 것 같습니다.종속 기본 클래스에서 형식 액세스

template <class T> 
struct Base 
{ 
    typedef T value_type; 
}; 

template <class T> 
struct Derived : Base<T> 
{ 
    // Version 1: error on conforming compilers 
    value_type get(); 

    // Version 2: OK, but unwieldy for repeated references 
    typename Base<T>::value_type get(); 

    // Version 3: OK, but unwieldy for many types or deep inheritance 
    typedef typename Base<T>::value_type value_type; 
    value_type get(); 

    // Version 4: why doesn't this work? 
    using typename Base<T>::value_type; 
    value_type get(); // GCC: `value_type' is not a type 
}; 

나는 여러 수준의 상속을 통해 상속하고 싶은 할당 자 스타일 typedef 집합을 기본 클래스로 사용합니다. 지금까지 찾은 최고의 솔루션은 위의 버전 3이지만 버전 4가 작동하지 않는 이유가 궁금합니다. GCC는 using 선언을 수락하지만 그것을 무시하는 것처럼 보입니다.

C++ 표준, C++ Prog를 확인했습니다. 랭. 3rd ed. [Stroustrup] 및 C++ Templates [Vandevoorde, Josuttis]를 사용하고 있지만 use-declaration을 종속 기본 클래스 유형에 적용 할 수 있는지 여부는 다루지 않습니다.

다른 예인 GCC 메일 링리스트에 here is the same question being asked (실제로 대답하지는 않음)을 보는 것이 도움이 될 경우에 유용합니다. asker는 그가 'typename을 사용하는'것을 다른 곳에서 보았다는 것을 나타내지 만, GCC는 그것을 지원하는 것 같지 않습니다. 필자는 테스트 할 수있는 다른 컴파일러를 가지고 있지 않습니다.

+0

준수하는 컴파일러에 대해 (사용자의 의견으로는) 컴파일해야하지만 작성하지 않아야하는 코드를 게시하십시오. 템플릿을 어떻게 사용하고 있는지 게시하십시오. –

+0

나는 모든 관련 정보가 위에 있다고 믿습니다. 버전 1 ~ 4는 MSVC 9에서 작동합니다. MSVC 9는 비 규격 1 단계 이름 확인 기능 (즉, 인스턴스화 시점)을 가지고 있습니다. 버전 2와 3만이 GCC 4.3에서 작동합니다. 버전 4가 유효하지 않은 이유는 모르지만 GCC는이를 수락하지 않습니다. 사용 방법은 이것이 인스턴스화되는 방법과 별 상관이 없습니다. 템플릿 선언을 컴파일하려고합니다. 위의 코드는 훨씬 복잡한 컨테이너 어댑터의 단순화입니다. –

+0

여기에 코드를 게시 할 때 사람들이 컴파일 할 수 있도록 코드를 편집해야한다고 생각하지 마십시오. –

답변

8
리차드 Corden가 지적 하듯이,이 문제는 2003 년 표준이 비준 된 후 C++ Standard Core Language Defect Reports에서 해결 된

: (2003 10월 개정 2003 년 4 월 ) How do the keywords typename/template interact with using-declarations?

제안 해상도 :

새로운 추가하기 문단 하단에 7.3.3 [namespace.udecl] :

사용 선언에 키워드 typename을 사용하고을 지정하는 경우종속 이름 (14.7.2 [temp.dep]), using 선언에 의해 도입 된 이름은 typedef-name (7.1.3 [dcl.typedef])로 처리됩니다. bug 14258에 설명 된대로

이 텍스트 년 10 월 15 일부터 2 판 표준에 표시하지 않는 것

, 2003

GCC는 아직,이 해상도를 구현하지 않습니다

을 - ----- Comment # 3 Giovanni Bajo 출신 2004-02-27 12:47 [대답] ------- 문제는 우리 USING_DECL이 인 "typename"을 기록하지 않는다는 것입니다. 사실 이라는 유형입니다. 이것은 암시적인 타입 이름 확장 덕분에 덕분에 사용되었습니다.

중복 bug 21484은 'typename 사용'이 Comeau 및 Intel 컴파일러에서 작동 함을 나타냅니다. MSVC는 모든 이름을 종속 변수로 처리하기 때문에 해당 컴파일러에서는 구문을 사용할 필요가 없지만 허용됩니다. GCC 4


Fixed.2011 12 월 13 일, 7!

+1

이것은 버그이지만 비교적 최근에야 gcc에서 너무 열심히해서는 안된다. 다음 핵심 쟁점은 단어 변경 "http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#11"을 강조 표시합니다. 이것은 C++ '03 표준에 들어갔습니다. –

+0

고마워요, 리처드, 제가 찾고 있던 정확한 링크입니다! –

-1

Base :: value_type에 대한 typedef를 선언하기 전에 Base에 대한 템플릿에 액세스 지정자 (public/protected/private)를 포함하지 않았습니다. 결과적으로 private로 기본 설정되며 Base에서 파생 된 클래스에서 액세스 할 수 없습니다.

+5

그는 Base/Derived 형식을 구조체로 정의 했으므로 멤버는 기본적으로 private가 아닌 public * public *입니다. – luke

관련 문제