.template / ::template / ->template

2022. 3. 23. 13:32C++

struct A
{
    template <typename T>
    void Foo();
};

template <typename T>
void Call(T arg)
{
    arg.Foo<int>(); // ERROR!
}

 

위 코드에서 arg.Foo<int>() 함수 콜은 다음과 같은 컴파일 에러가 발생한다.
(clang, gcc에서는 컴파일 에러가 발생하며, msvc에서는 정상적으로 컴파일 된다.)

error: use 'template' keyword to treat 'Foo' as a dependent template name

이 문제는 템플릿 파라미터에 의존하는 오브젝트의 템플릿 멤버함수를 호출하려고 할 때 발생하는 문제로,

컴파일러가 < 토큰이 less-than을 의미하는지, 아니면 템플릿 인자 리스트의 시작을 의미하는지 알 수 없기 때문이다.

 

위 컴파일 에러가 말해주듯, 코드를 다음과 같이 변경하여 컴파일러에게 힌트를 주면 문제를 해결할 수 있다.

struct A
{
    template <typename T>
    void Foo();
};

template <typename T>
void Call(T arg)
{
    arg.template Foo<int>(); // OK!
}

 

.template 외 ::template, ->template도 같은 방식으로 사용할 수 있다.

 

[참고]

- C++ Templates: The Complete Guide, 2nd Edition