컴파일러는 구조상 어떤 식별자를 보았을 때 '값'인지 '타입'인지 결정해야한다.
template <typename T>
int func() {
T::t* p;//곱하는걸까 포인터 선언을 하는 것일까?
}
class A {
const static int t;
};
class B {
using t = int;
};
위에서, 클래스 A에 대해 func함수를 특수화 한다면, t가 어떠한 int값이 되어 T::t* p;가 단순히 클래스 A의 t와 p를 곱하는 식으로 해석된다.
반면에, func함수가 클래스 B에 대해 특수화 된다면, T::t* p;는 int형 포인터 p를 선언하는 꼴인 된다. 따라서 컴파일러는 이 두 상황을 명확히 구분하기 위해 T::t가 타입인지 값인지 명확하게 알려줘야한다.
이렇게 템플릿 인자에 따라 어떠한 타입이 달라질 수 있는 것을 의존타입(dependent type)이라고 부른다. 따라서 컴파일러가 문장을 성공적으로 해석하기 위해서는 반드시 우리가 쓸 T가 타입인지 값인지 알려줘야한다. 타입임을 명시할때는 typename
을 붙여주기만 하면 된다.(컴파일러는 기본적으로 값으로 인식하기 때문에 값은 명시해줄 필요없음)
TMP를 활용하면, 단위 연산을 컴파일 타임에 에러 없이 구현할 수 있다. 즉, 단위가 다른 값끼리 연산이 애초에 호환되지 않도록 강제할 수 있다는 뜻이다.