템플릿 멤버 함수를 특별하게 구분해야 할 필요가 있는 경우 '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'을 앞에 붙여 보자.


원문 : 

https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/keyword_template_qualifier.htm

Posted by kukuta
TAG ,

댓글을 달아 주세요