2014-12-29 2 views
4

현재 C++ 컴파일러 (최신 GCC, 그 소리는) 아래의 예에서 typename 키워드 필요합니다 typename는 GCC (4.9, 5.0)를 생략 오류보고있다함수 템플릿 내에서 선언 된 경우 로컬 클래스에 종속됩니까?

template<class T> 
struct A 
{ 
}; 

template<class T> 
void f(T) 
{ 
    struct C 
    { 
    }; 
    typedef typename A<C>::Type Type; // typename required 
} 

경우

need 'typename' before 'A<f(T)::C>::Type' because 'A<f(T)::C>' is a dependent scope

이 예를 그렇지 않으면 C++ 11 표준을 읽었을 때 잘 형성됩니다.

이 문제는 다음과 같은 표현에 의해 덮여있는 것 같다 : 그러나

[temp.dep.type]/8

A type is dependent if it is

  • a template parameter,

  • a member of an unknown specialization,

  • a nested class or enumeration that is a member of the current instantiation,

  • a cv-qualified type where the cv-unqualified type is dependent,

  • a compound type constructed from any dependent type,

  • an array type constructed from any dependent type or whose size is specified by a constant expression that is value-dependent,

  • a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent, or

  • denoted by decltype(expression), where expression is type-dependent.

클래스가 C로컬 클래스보다는 중첩 클래스이다 class.local] 방법. 그렇다면 A<C>을 부양 가족으로 취급해야하는 이유는 무엇입니까?

EDIT 보너스 포인트

, 다음과 같은 예 C에 부재 ENUM을 추가하여 변경되는 경우 :

template<typename T> 
struct A 
{ 
    typedef T Type; 
}; 

template<class T> 
void f(T) 
{ 
    struct C 
    { 
     enum { value = T::value }; 
    }; 
    typedef typename A<C>::Type Type; // typename required 
} 

A<C> 지금 따라 취급되어야 하는가?

+2

이것은 DR 1484와 관련이있는 것 같습니다. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html – willj

+2

그들은 DR 페이지에서 앵커를 사용하므로 링크를 제공 할 수 있습니다 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1484 – dyp

+1

'typename'이 필요하다고 생각합니다. 다음과 같은 별난 예제를 고려해보십시오. http://coliru.stacked-crooked.com/a/a03aebd672bfa7c7 'C'의 정의 *는 이름이 아니더라도 템플릿 매개 변수에 따라 달라질 수 있습니다. – dyp

답변

4

내 이해 (표준의 현재 표현)에 따르면, 예에서 C은 종속적이지 않습니다. A<C>::Type도 아니므로 typename이 필요하지 않습니다.

중첩 된 클래스 템플릿과 함수 템플릿의 로컬 클래스에는 근본적인 차이가 있습니다. 후자는 특수화 될 수 없으므로 함수 템플릿 내부의 로컬 클래스에 대한 참조는 동일합니다. 즉, f의 모든 전문화 과정에서 C은이 함수 템플릿 f에 정의 된 클래스 C을 말합니다. 그러나

template <typename T> 
class A { class C{}; }; 

template <> 
class A<int>::C { int i; }; 

:

A type is dependent if it is

  • a compound type constructed from any dependent type,
즉 (/(1.6 [temp.expl.spec]에 덮여로) 당신은 참으로 명시 적으로 자신의 회원을 전문 수있는 클래스 템플릿의 경우) 아니다

따라서 정의가 dyp's example과 같이 수행 된 경우 CT에서 구성되므로 종속적입니다.
표준 문구에는 주석 섹션에서 논의중인 불명료 함이 있습니다 (예 : T에 의존하는 멤버 함수의 정의와 그 클래스 종속성으로의 전환 방법에 대해 설명합니다.

+0

분명히하기 위해 템플릿 클래스에 정의 된 * 모든 * 중첩 클래스는 종속적입니다. '템플릿 구조체 A {구조체 B {}; void f() {B b; }};', 당신이 발견 한 문언의 변화는'B'를 의존하지 않게 만든다. 예를 들어 다음과 같은 전문화가있을 수 있기 때문에 불가능합니다. 'A :: B'. 그러나 나는 지역 클래스가 비 종속적 일 수 있다는 것을 당신과 동의하고 있다고 생각합니다. – hvd

+0

'A '을 전문화하지 않고'A :: B'를 전문화 할 수 있습니다 : template struct A {struct B {int && m;}; void f() {B b; }}; 템플릿 <> 구조체 :: B {}; int main() {A () .f(); }'완벽하게 유효합니다. – hvd

+0

@hvd 아, 맞습니다. * "이름은 현재 인스턴스화 의 멤버 인 경우 현재 인스턴스화의 종속 멤버입니다.이 인스턴스는 조회 될 때 현재 인스턴스화중인 클래스의 멤버 중 적어도 하나를 참조합니다. 곧 대답 해. – Columbo

0

다음은 제 추론입니다. 도움이되기를 바랍니다. 로컬 Cf이 인스턴스화 될 때까지 인스턴스화하지 않습니다. 따라서 A<C>은 인스턴스화가 아니며 컴파일러가 그것을 볼 때 불투명합니다. 불투명도 때문에 컴파일러에서는 A<C>::Type이 중첩 된 형식 이름인지 또는 데이터 멤버 또는 메서드인지 여부를 확인할 수 없습니다. 그러나 기본적으로 컴파일러에서는 중첩 된 형식 이름으로 A<C>::Type을 볼 수 없습니다. 따라서 명시 적 사양이 필요합니다.

+0

그러나이 질문은 언어 변호사와 함께 태그가 붙어 있으며 표준을 참조하기 때문에 공식적인 언어 규칙을 사용하여 주장을 뒷받침해야합니다. – BartoszKP

+0

@BartoszKP 당신 말이 맞아요. 어쨌든, 여기 당신의 관심에 대한 몇 가지 추측이 있습니다. 컴파일러에서 생성 된 오류 메시지는 범위가 종속 형식 인 경우 중첩 형식 자체가 비 종속적 인 경우에도 명시 적 사양을 요구한다는 것을 나타냅니다. 내포 된 유형이 범위에 관계없이이 경우에 인스턴스화되어야하는지 여부는 구현에 따라 결정됩니다. – Lingxi

+0

나는이 문제에 관해서 논의하고 싶지 않다. 나는 단지 당신이 당신의 대답을 향상 시키도록 격려하려고했다. 콜럼보의 대답에서 볼 수 있듯이, "구현에 의해 정의 된"주장은 어쨌든 잘못되었다. – BartoszKP

0

표준에 여기에 typename 키워드가 필요하다는 것을 나타내는 항목이없는 것 같습니다. 이 문구에는 GCC가 (기능 템플릿 전문 분야의 로컬 클래스)을 처리하기위한 단축키를 T —에 종속적으로 사용하도록 유도했을 수도있는 A<[f<T>(T)::]C>::Type이 종속적 인 것으로 명시되어 있지 않습니다.

Core defect 1484이 문제에 특별히 제기 된 것은 아니지만 제안 된 추가 비표준 텍스트가 의도를 명확하게 만들고 GCC 표준에 따라 typename 키워드를 요구하지 않는다고 생각합니다.

관련 문제