템플릿 멤버 함수를 특별하게 구분해야 할 필요가 있는 경우 한정자로써 'template' 키워드를 사용한다. 아래 예제 코드를 보고 언제 'template' 키워드를 한정자로 사용해야 하는지 살펴보자
class A
{
public :
template<class T> T function_m() {};
};
template<class U> void function_n(U argument)
{
char object_x = argument.function_m<char>();
}
위 예제에서, 컴파일러는 템플릿 인자 U가 클래스 A의 인스턴스라는 것을 추론하지 못하기 때문에 'function_m'이 템플릿 멤버 함수라는 것을 알지 못하고 '<'를 비교연산자로 처리 버려 컴파일 오류가 발생한다. 컴파일러에게 이것이 템플릿 함수를 호출하는 것이라는 것을 알리기 위해선 아래와 같이 'template' 한정자를 함수 호출부 앞에 추가 해주어야 한다
char objec_x = argument.template function_m<char>();
만일 템플릿 특수화 멤버 함수의 이름이 ., -> 또는 :: 연산자 뒤에 나온다면, 그리고 그 이름이 명시적으로 한정된 템플릿 인자라면, 'template' 키워드를 꼭 앞에 붙여 줘야 한다. 다음 예제를 살펴 보자
#include <iostream>
using namespace std;
class X
{
public :
template<int j> struct S
{
vodi h()
{
cout << "member template's member function:" << j << endl;
}
};
template<int i> void f()
{
cout << "primary: " << i << endl;
}
};
template<> void X::f<20>()
{
cout << "specialize, not-type argument = 20" << endl;
}
template<class T> void g(T* p)
{
p->template f<100>();
p->template f<20>();
typename T::template S<40> s; //멤버 템플릿 앞에 스코프 오퍼레이터를 사용한다
s.h();
}
int main()
{
X temp;
g(&temp);
}
위 예제의 결과물을 보자 :
primary: 100
specialized, non-type argument = 20
member template's member function: 40
위에서 'template' 키워드를 사용하지 않았다면 컴파일러는 '<'를 비교 연산자로 해석한다. 아래는 오류를 발생 시키는 예다 :
p->f<100>();
컴파일러는 템플릿 멤버 함수 f를 일반 함수로 해석하고 '<'를 비교 연산자로 해석하여 오류를 발생 시킨다.
요약
- 템플릿 형태로 넘겨 받은 인자의 템플릿 클래스 인스턴스의 템플릿 함수를 호출 할때는 'template' 키워드를 한정자로 붙여야 한다.
- 템플릿 멤버 함수를 썼는데 오류가 발생하면 일단 'template'을 앞에 붙여 보자.