1. typename


위에서 Line 6의 T::test는 type T에서 test를 꺼내는 것인데,
이때 test는 두 가지로 해석할 수 있다.



1) static 변수를 꺼내는 경우



2) class 내의 type을 꺼내는 경우 (typedef 또는 class 내에 정의된 클래스)

1), 2) 처럼 실제 type인 경우에는 컴파일러가 둘을 구분하는데에 문제가 발생하지 않는다.
(만일 같은 이름의 static 변수와 타입이 있을 경우 이미 정의된 것을 재정의 한다고 컴파일 에러가 발생)

하지만 맨 첫번째 경우처럼 template argument 인 경우 컴파일 time에 둘을 결정할 수 없다.



이를 막기 위해 T::type 앞에 typename을 붙여서 컴파일러에게 typename이란 것을 명시해야 정상 동작한다.



Line 5처럼 typename을 앞에 붙이면 T::type을 type으로 여겨서 뒤의 *를 포인터로 해석하고, 정상적으로 동작한다.



2. template


class 안에 template이 있는 경우를 생각해 보자.

(템플릿 멤버함수 또는 클래스 안의 템플릿 클래스)




이 경우 Line8은 컴파일러가 CCC 내부의 print가 template인 것을 확인하여 <를 해석할 수 있지만,


Line 9는 T::print가 static variable인지 구분 되지 않고,

<를 대소 연산자로 확인하여야 하는지 구분이 되지 않아 에러가 발생한다.


이를 막기 위해서는 T::template print<int>(x) 로 수정하여 print가 template 임을 명시하여야 한다.


만일 template 함수가 아니고 template class인 경우는, 1의 typename 까지 같이 붙여줘야 한다.




Line 11은 typename 과 template 둘 다 있어야만 에러가 발생하지 않는다.




3. value_type


임의의 container (vector, list 등) 에서 안에 들어 있는 값을 꺼내야 할 경우, type은 어떻게 해야 할까?



예시로 container 가 list<int> 로 들어온다면 ? 에 int를 넣으면 되겠지만, list<double> 이라면 ?에 double이 들어가야 한다.

즉, template에 따라서 x의 type이 바뀌는데 이는 T를 통해 유추할 수 없다.


이를 해결하려면, template 인자를 두 개를 (list<int>, int) 받는 방법이 있다.

(아니면 template template parameter로 list를 받고, int를 받는 방법이 있다.)



foo1, foo2 둘 다 가독성이 떨어진다.


이때 list, vector 안에서 typedef로 안의 값의 타입을 보관하고 있다면, foo 안에서 쉽게 꺼낼 수 있다.



이때 Line 10에서 꺼낼 경우 2번에서 언급한 typename 을 사용해야지 컴파일 에러 없이 type을 꺼낼 수 있다.


STL은 이런 값들이 많이 정의되어 있는데, 정리하면 아래와 같다.

침고: std::vector 링크


value_type

T

 allocator_type

Allocator

size_type

unsigned int, size()의 return type

difference_type

(signed) int, 두 pointer를 뺐을 경우의 type

 reference

 T&

 const_reference

 const T&

 pointer

 Allocator::pointer

 const_pointer

 Allocator::const_pointer

 iterator

 임의 접근 반복자

 const_iterator

 상수형 임의 접근 반복자

 reverse_iterator

 reverse_iterator (맨 뒤 원소에서 시작해서 앞으로)

 const_reverse_iterator

 const reverse iterator


'프로그래밍 > C++' 카테고리의 다른 글

템플릿 주의할 점  (0) 2018.12.24
템플릿 (Template)  (0) 2018.11.04
함수 바인딩  (0) 2018.10.29
가상 함수 (Virtual Function)  (0) 2018.10.23
상속 (Inheritance)  (0) 2018.10.22

+ Recent posts