2013-02-13 3 views
3

왜이 코드가 컴파일되지 않습니까?템플릿 매개 변수의 정적 멤버 템플릿 사용

struct A { 
    template <class T> 
    static T a(int i) { return 2*i; } 
}; 

template <class T> 
struct B { 
    double b; 
    B(): b(T::a<double>(5)) {} 
}; 

template class B<A>; 

컴파일러는 템플릿 인스턴스화에 도달하지 않습니다. 나는 gcc 4.7.0을 사용하고있다. a 종속 이름 (또는 그런 일이)이기 때문에

test.cc: In constructor »B<T>::B()«: 
test.cc:9:25: Error: expected »(« before »<« token 
test.cc:9:26: Error: expected primary-expression before »double« 
+1

아마도 컴파일러 오류 메시지를 제공 할 수 있습니까? – ronag

+0

죄송합니다, 깜빡했습니다 –

답변

6

당신은 template 키워드를 놓치고있어.

B(): b(T::template a<double>(5)) {} 

은 (또한 마지막 줄은 template struct B<A>;해야합니다.) 피투성이 자세한 내용은

, 참조 : Where and why do I have to put the "template" and "typename" keywords?

2

을 당신은 메소드 이름 앞에 template을 추가해야한다

B(): b(T::template a<double>(5)) {} 

템플릿 클래스 B을 구문 분석 할 때 컴파일러에서 T::a은 템플릿 화 된 방법이므로 (T은 그 전에 지정되지 않았고 T::a은 완전히 알려지지 않았기 때문에) <double>을 템플릿 매개 변수 목록으로 구문 분석해야한다는 것을 알지 못합니다.

T::adouble보다 작고 (0)보다 큰 것으로 해석 될 수 있습니다. 물론 double은 표현식이 아니므로 실패합니다. 따라서 오류 메시지. 따라서 컴파일러 이 템플릿 함수 호출이되기를 원한다고 가정합니다. 그러나 형식이 아닌 템플릿 매개 변수를 사용할 수도 있습니다. 예를 들어 int라고 가정하면 T::a<42>(5)은 템플릿이 아닌 42보다 작은 T::a보다 작게 (5)보다 큰 것으로 구문 분석 될 수 있습니다. 그러나 이것을 으로 구문 분석하고 매개 변수 목록이 42이고 그 다음에 5 인 호출 연산자를 파싱하기를 원했습니다.

컴파일러에게 템플릿 기반 함수 호출임을 알리기 위해 함수 이름 앞에 template을 넣어야합니다.

0

컴파일러는 T::{something}을 작성할 때마다 {something}은 T의 멤버 변수 또는 메서드 중 하나라고 가정합니다. 그렇지 않은 경우 컴파일러가 무엇인지 말해야합니다. 당신이 말하는 키워드가 변수가 아닌 타입이라면 당신이 사용해야하는 typename 키워드에 대해 알고있을 것입니다. 템플릿 회원을위한 유사한 트릭이있다 :

template <class T> 
struct B { 
    double b; 
    B(): b(T::template a<double>(5)) {} 
}; 

지금 컴파일러는 a 템플릿이며, 그 무엇 그 다음에 오는 것은 템플릿 매개 변수 목록입니다 알고있다.

관련 문제