template <typename T>
는 아래에 정의되는 클래스에 대해 템플릿을 정의하고, 템플릿 인자로 T 를 받게 되며, T 는 반드시 어떠한 타입의 이름임을 명시함.
이때 아래에 함수가 온다면 이 함수에 대한 템플릿을 정의하는 것임.
Vector<int> int_vec;
위와 같이 초기화함.
위 코드는 Vector의 T가 int로 치환된 클래스의 객체 int_vec을 생성하는 것.
클래스 템플릿 인스턴스화: 클래스 템플릿에 인자를 전달해서 실제 코드를 생성하는 것
템플릿은 인스턴스화되어야 -> 컴파일러가 실제 코드를 생성함.
BUT bool 데이터를 보관하는 벡터와 같이, 1개 비트로 충분히 처리할 수 있으나 8비트나 이용해야 하는 상황에서(c++은 기본 처리 단위가 1byte임) 특별히 따로 처리해줘야 함.(다음 장 참고)
템플릿 특수화: 일부 경우에 대해서 따로 처리하는 것
template <typename T> class Vector {
T* data;
int capacity;
int length;
// ... 생략
};
template <>
class Vector<bool> {
unsigned int* data;
int capacity;
int length;
// ... 생략
};
// T가 bool인 경우, 즉 특수한 경우에 대해 처리
이와 같이 bool의 경우 따로 처리할 수 있음.
이때 bool을 1bit로 처리하는 방법에 대해 다룸 - 숙지하고 넘어가는 거 추천
#include <iostream>
#include <string>
template <typename T>
T max(T& a, T& b) {
return a > b ? a : b;
}
int main() {
int a = 1, b = 2;
std::cout << "Max (" << a << "," << b << ") ? : " << max(a, b) << std::endl;
// Max (1,2) ? : 2
std::string s = "hello", t = "world";
std::cout << "Max (" << s << "," << t << ") ? : " << max(s, t) << std::endl;
// Max (hello,world) ? : world
}
Function Object = 함수 객체(Functor): 함수는 아니지만 함수인 척을 하는 객체
아래 코드에서 comp 객체에 유의해서 살펴 보자.
template <typename Cont, typename Comp>
void bubble_sort(Cont& cont, Comp& comp) {
for (int i = 0; i < cont.size(); i++) {
for (int j = i + 1; j < cont.size(); j++) {
if (!comp(cont[i], cont[j])) {
cont.swap(i, j);
}
}
}
}
comp는 함수가 아니라 객체 이지만 Comp 클래스에서 () 연산자를 오버로딩해서 마치 함수처럼 사용할 수 있도록 한 함수 객체인 것이다.
struct Comp {
bool operator()(int a, int b) {
return a > b;
}
};
아래 사진 참고.
여기 링크 참고
-> 이해 잘 안됨
유튜브 링크 1: 함수 포인터
유튜브 링크 2: 함수 객체와 람다
#include <iostream>
template <typename T, int num>
T add_num(T t) {
return t + num;
}
int main() {
int x = 3;
std::cout << "x : " << add_num<int, 5>(x) << std::endl;
// x : 8
}
위와 같이 template <typename T, int num>
을 쓸 수 있음
#include <iostream>
template <typename T, int num = 5>
T add_num(T t) {
return t + num;
}
int main() {
int x = 3;
std::cout << "x : " << add_num(x) << std::endl;
}
템플릿 디폴트 인자는 함수 디폴트 인자랑 똑같이 인자 뒤에 = (디폴트 값)을 넣어주면 된다.
#include <iostream>
#include <string>
template <typename T>
struct Compare {
bool operator()(const T& a, const T& b) const {
return a < b;
}
};
// 🥰 아래에 집중
template <typename T, typename Comp = Compare<T>>
T Min(T a, T b) {
Comp comp;
if (comp(a, b)) {
return a;
}
}
int main() {
int a = 3, b = 5;
// 🥰 아래에 집중
std::cout << "Min " << a << " , " << b << " :: " << Min(a, b) << std::endl;
std::string s1 = "abc", s2 = "def";
std::cout << "Min " << s1 << " , " << s2 << " :: " << Min(s1, s2)
<< std::endl;
}
/*
<실행 결과>
Min 3 , 5 :: 3
Min abc , def :: abc
*/