2013-02-14 2 views
0

은 가정하자 나는 다음과 같은 코드를 한 : ICC 13.0.1와 연타 3.2이 나에게 준, 4.7.2 및 GCC 4.8.0는 확인이 코드를 컴파일다른 행동 - 템플릿 템플릿 인수

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

template <typename T> 
class B 
{ 
    A<B> instance; 
}; 

int main() 
{ 
    B<int> instance; 
} 

GCC를하는 동안 오류 (clang은 B 대신 B를 요구하고 icc는 템플릿 인스턴스에서 < 뒤에 공백이 필요함).

누가 맞습니까?

나는 그것에 관한 스레드 (Template class that refers to itself as a template template parameter?)를 찾았지만 표준의 14.6.1/2를 이해할 수 없으며 또한 LLVM 버그 14350 (http://www.mail-archive.com/[email protected]/msg21095.html)을 보았습니다. 그럼 여기에 잘못하고 인텔이 틀렸어?

답변

1

14.6.1는 말한다 :

주입 된-클래스 이름이 템플릿 이름 또는 유형 이름로 사용할 수 있습니다. 이 템플릿 템플릿 매개 변수에 대한 템플릿 인수 같은 템플릿 인수 목록와 함께 사용하는 경우, 또는 의 마지막 식별자로 정교 형 지정자 친구 클래스 템플릿 선언의을 클래스 템플릿 자체를 참조합니다.

"injected-class-name"은 클래스 템플릿의 이름 (B)이 클래스 범위에 "주입 됨"입니다. 즉, 이는 B 클래스 정의 내에서 규정되지 않은 이름 B의 사용을 나타냅니다. 명시 적 템플릿 인수 (B<int>) 또는 템플릿 템플릿 매개 변수 (A<B>)를 사용하는 템플릿의 템플릿 인수로 템플릿 이름이 필요한 컨텍스트에서 해당 이름을 사용하는 경우 템플릿 자체를 참조해야합니다.

그래서 gcc가 맞습니다.

또한 C++ 11에서는 < 다음에 공백이 없어야합니다. <::B>.

다음 3 개 문자 <::하고 후속 문자 자체로 전처리 토큰으로 처리하여도 :>< 인 경우 : 2.5, 제 3 항, 입력 스트림을 토큰으로 나눈 따르면 대체 토큰 <:의 첫 번째 문자가 아닙니다. (<:[을 쓰는 또 다른 방법입니다.)

+0

이러한 상황에서 B와 B 형식을 모두 사용할 수 있습니까? – FrozenHeart

+0

@NikitaTrophimov, 템플릿을 참조 할 때':: B'를 사용할 수 있습니다. – rici