1. template은 function이나 class가 아니다.


이걸 헷갈리면 function 또는 class를 넣어야 할 곳에 template을 넣어서 에러가 발생하게 된다.



만일 템플릿 인자로 템플릿을 넣어야 할 때는 템플릿 템플릿 파라미터를 써야 한다.




2. 선언부와 구현부를 분리할 때



2-1. 선언부

전체적으로, class 정의 내에서는 <T>를 명시해주지 않아도 된다.

- Line 11, 35: 디폴트 생성자

템플릿 인자의 기본값은 x = 0 으로 해도 되지만 x = T() 처럼 디폴트 생성자를 호출해주는 것이 더 좋다.

알다시피 기본 인자는 선언부에만 적고 구현부에 쓰지 않는다.


- Line 12, 37: 복사 생성자

복사 생성자에는 Test<T>& 대신 Test& t로 해도 되지만, 전자가 더 명확하다.


- Line 19: ostream& operator << 와 friend의 문제. (참고링크)

1. Extrovert: template 으로 operator<<를 friend 선언하고, 외부에 구현

이때 문제는 서로 다를 수 있는 Test<T>, Test<U>에 대해서 operator<<가 다 friend 등록되어 버린다는 점에 있다.

(Line 20의 template<typename U>를 제거하고 Test<T>로 변경하면 warning 발생

2. Introvert: 선언 후 바로 구현

이렇게 하면 다른 Test<U>에 대해서는 friend 되지 않는다.

이 경우는 선언-구현을 나눌 수 없다.

3. Taking advantage of extrovert

미리 외부에 operator<<를 template function으로 선언해 놓으면 1번과 달리 friend operator<<가 template이 아니고, Line 27처럼 class template argument T를 그냥 갖다 쓸 수 있다.

이 경우 구현부는 1번과 동일하게 가져가도 된다.


2-2. 구현부


* 템플릿은 선언부와 구현부를 헤더파일과 소스파일로 분리할 수는 없다.


- 모든 메소드마다 Test<T>를 붙여야 해서 template <typename T>도 다 붙여줘야 한다.


- Static 변수

Line 29의 static 변수는 클래스 내부에 선언하였으면 Line 58처럼 클래스 외부에서도 한번 초기화하여야 한다.




3. 템플릿 멤버 함수 (Template member function)


Line 30은 template member function의 선언이고, line 60은 구현이다.

여기서 Line 61을 따로 쓰지 않고 Line 60에 template <typename T, typename U> 로 한번에 쓰면 에러가 발생한다.


3-1. 일반화된 복사 생성자


현재 복사 생성자는 Line 12에 선언된 대로 같은 Test<T>에 대해서만 선언되어있다.

이를 테면 Test<int>와 Test<short>는 다른 타입이기 때문에 복사 생성 시 에러가 발생한다.

Test <short> r = p; // error

이를 막으려면 서로 다른 Test<T>, Test<U> 간에 복사 생성자를 추가해줘야 한다.

이는 템플릿 멤버 함수로 구현할 수 있다.

이때, Test<T>와 Test<U>는 서로 다른 클래스이므로 friend로 등록해주어야 한다.



이렇게 복사 생성자가 제공되면 ==, !=도 제공해주어야 한다.


shared_ptr 등의 스마트 포인터를 구현하는 경우 반드시 일반화된 복사 생성자가 있어야 한다.

(파생 클래스를 shared_ptr 로 받는 경우 서로 다른 클래스를 복사 생성할 수 있어야 한다.)


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

typename명령어, template 명령어  (0) 2018.12.26
템플릿 (Template)  (0) 2018.11.04
함수 바인딩  (0) 2018.10.29
가상 함수 (Virtual Function)  (0) 2018.10.23
상속 (Inheritance)  (0) 2018.10.22

+ Recent posts