모든 내용은 [윤성우 저, "열혈 C++ 프로그래밍", 오렌지미디어] 를 기반으로 제 나름대로 이해하여 정리한 것입니다. 다소 부정확한 내용이 있을수도 있으니 이를 유념하고 봐주세요!
# 템플릿
- 컴파일 타임에 클라이언트가 여러 타입의 함수나 클래스를 쉽게 생성하게 함
- 서버 코드 작성자(프로그래머)는 좀 더 제네릭 프로그램 코드를 만들고,
클라이언트가 구체적인 코드를 작성함으로써 제네릭한 프로그래밍이 가능해짐
- T는 템플릿 매개변수이며 클라이언트에서 결정함 => 템플릿의 인스턴스를 만들어냄
- 템플릿 선언에는 다양한 자료형(기본 자료형 포함) 선언 가능 + 둘 이상의 자료형에 대해도 가능
- 템플릿의 매개변수로 템플릿 매개변수 T 뿐만 아니라, 정수 등의 기본 자료형도 가능
e.g. template<typename T1, typename T2, int T3, ...>
- 템플릿 인스턴스는 컴파일러가 생성한 "함수(또는 클래스)의 정의"이다.
- 컴파일이 완료되면 함수(또는 클래스) "템플릿"은 존재하지 않으며,
템플릿 인스턴스화된 함수(또는 클래스)만 존재할 뿐임
- 템플릿의 매개변수도 함수의 매개변수처럼 디폴트 매개변수 값을 지정할 수 있음
# 템플릿의 유형
1. 함수 템플릿
- 함수를 만드는데 사용하는 템플릿
- 함수 템플릿을 통해 템플릿 함수(템플릿 기반으로 만들어진 함수, 일반 함수와는 구분됨)를 생성
- 함수 템플릿은 함수의 기능은 결정되었으나, 자료형은 결정되지 않은 상태
- 템플릿 함수는 자료형당 하나씩만 만들어지며, 컴파일 할때 만들어진다.
(따라서, 컴파일 속도는 느려지나 런타임 속도는 느려지지 않는다.)
e.g.
template <typename T>
void Print(T data)
{
cout<<data<<endl;
}
*함수 템플릿 특수화
e.g.
template <typename T>
void Print(T data)
{
cout<<data<<endl;
}
template <>
void Print(char data) // 템플릿 매개변수 T를 char형으로 특수화
{
cout<<data<<endl;
}
2. 클래스 템플릿 : 이를 이용해 템플릿 클래스를 생성
e.g.
template <typename T>
class A
{
...
};
- 클래스 템플릿은 클래스의 메타코드일 뿐,
컴파일러는 클래스 템플릿(클래스 메타코드)를 이용해 실제 클래스(클래스 정의 코드)를 생성
- 클래스 템플릿도 특수화가 가능
*클래스 템플릿 특수화
template <typename T>
class A
{
...
};
template<> // 기존 템플릿 매개변수 T를 string으로 특수화
class A<string>
{
...
}
# cout<<typeid(객체).name() : 해당 객체의 자료형(타입명)이 무엇인지 출력
# C++에서는 C와 다르게 (int)3.14와 더불어 int(3.14) 형변환도 허용
# 클래스 템플릿 선언시에도, 멤버함수의 선언과 정의 분리가 가능하다.
- 그러나 "반드시" 함수 정의 부분에서
template <typename T>
반환형 클래스명<T>::함수이름(매개변수)
위와 같은 형식을 지켜야만 한다.
# 매개변수의 디폴트값은 클래스와 동일하게 클래스 탬플릿 내에만,
정확하게는 멤버함수의 선언 부분에만 표기한다.
# 생성자 외부에 정의시에는 일반 클래스와 동일하게 외부 생성자 정의에만 이니셜라이저 삽입!
# 컴파일은 파일단위로 이루어진다는 것을 반드시 기억하자.
(include 하지 않으면 파일간 서로를 참조하지 않음을 유의하자.)
- 따라서 템플릿의 경우에는
1) 템플릿 정의가 담겨있는 소스파일을 include 해서라도,
템플릿의 모든 정보를 템플릿을 사용할 소스파일에 전달하거나
2) 아니면 템플릿 선언과 정의를 분리하되, 헤더파일에 정의까지도 작성
# 클래스 템플릿 내에서도 friend 선언이 가능하며,
템플릿 클래스를 인자로 하는 일반 함수의 선언 및 정의도 가능하다.
# 함수 템플릿 특수화가 가능하듯, 클래스 템플릿 특수화도 가능하다.
- 특정 자료형을 기반으로 생성된 객체에 대해, 구분이 되는 다른 행동양식을 적용하기 위함이다.
# 함수, 클래스 템플릿의 부분 특수화도 가능하며, 전체 특수화가 부분 특수화보다 우선시된다.
# 템플릿 매개변수에 전달되는 자료형 정보 : 템플릿 인자
# 템플릿 매개변수
- 변수의 선언이 올 수도 있으며, 변수의 선언에 따라, 매우 비슷해보여도 객체의 타입이 달라질 수 있다.
- 템플릿 매개변수는 디폴트 값 지정도 가능하다.
# static 지역변수도 템플릿 함수 별로 각각 존재한다.
# static 멤버변수도 템플릿 클래스 별로 각각 존재한다.
# template<typename T> 와 template<>를 언제 쓰는가?
- 템플릿 관련 "정의"시,
1) 정의에 T가 존재하면 => template <typename T>
2) 정의에 T가 존재하지 않으면(그럼에도 템플릿 정의의 일부분임을 알려야하기에) => template<>
# 클래스 템플릿 정의의 일부인 초기화문을 대상으로도 특수화가 가능하다.
e.g.
template<>
long 클래스템플릿명::<long>::mem=5; (mem은 static 멤버변수)
[출처] : 윤성우 저, "열혈 C++ 프로그래밍", 오렌지미디어
'Programming > 열혈 C++ 프로그래밍(저자 윤성우)' 카테고리의 다른 글
Ch 16. C++의 형 변환 연산자 (0) | 2020.08.18 |
---|---|
Ch 15. 예외처리(Exception Handling) (0) | 2020.08.18 |
Ch 12. String 클래스의 디자인 (0) | 2020.08.17 |
Ch 11. 연산자 오버로딩 2 (0) | 2020.08.17 |
Ch 10. 연산자 오버로딩 1 (0) | 2020.08.17 |