본문 바로가기

진리는어디에

[C++] 'template' 키워드를 한정자로 사용하기

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

부록 1. 같이 보면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!