void Print(int a) { cout << a << endl; }
void Print(float a) { cout << a << endl; }
void Print(double a) { cout << a << endl; }
void Print(const char* a) { cout << a << endl; }
위처럼 자료형마다 Print 함수를 오버로딩하는 것은 코드 중복이 많아지는 비효율적인 방식입니다.
#include <iostream>
using namespace std;
template<typename T> // 템플릿 정의 (T는 타입 매개변수)
void Print(T a) {
cout << a << endl;
}
int main() {
Print<int>(50); // 명시적 타입 지정 가능
Print(50.0f); // 자동으로 float 타입으로 결정
Print(50.0); // double 타입으로 결정
Print("Hello World"); // const char* 타입으로 결정
return 0;
}
template<typename T>를 선언하여 T를 다양한 타입으로 변경 가능하게 합니다.Print<int>(50); → T를 int로 해석하여 실행됩니다.Print(50.0f); → T를 float로 해석하여 실행됩니다.특정 타입에 대해 일반적인 템플릿과 다르게 동작해야 할 때 사용합니다.
#include <iostream>
using namespace std;
class Knight {
public:
int _hp = 100;
};
// 기본 템플릿 (모든 타입에 대해 동작)
template<typename T>
void Print(T a) {
cout << a << endl;
}
// 특수화 템플릿 (Knight 타입에 대해 동작)
template<>
void Print(Knight a) {
cout << "Knight 특수화된 템플릿 호출" << endl;
cout << "HP: " << a._hp << endl;
}
int main() {
Print(50);
Print(3.14);
Print("Hello Template!");
Knight k;
Print(k); // 템플릿 특수화가 호출됨
return 0;
}
template<>를 사용하여 Knight 클래스에 대한 특수화 버전을 정의했습니다.Print(k);를 실행하면 일반적인 템플릿이 아니라 특수화된 템플릿이 호출됩니다.template<typename T1, typename T2>
void Print(T1 a, T2 b) {
cout << a << " " << b << endl;
}
int main() {
Print("Number:", 100); // "Number: 100" 출력
Print(3.14, 42); // "3.14 42" 출력
return 0;
}
template<typename T1, typename T2>를 사용하여 서로 다른 두 타입의 매개변수를 받을 수 있습니다.템플릿을 이용하여 반환 타입도 자동으로 결정할 수 있습니다.
template<typename T>
T Add(T a, T b) {
return a + b;
}
int main() {
int result1 = Add(1, 2); // int 타입으로 처리
float result2 = Add(1.5f, 2.3f); // float 타입으로 처리
cout << result1 << endl;
cout << result2 << endl;
return 0;
}
Add<int>(1, 2) → int 타입으로 해석됨.Add(1.5f, 2.3f) → float 타입으로 해석됨.함수뿐만 아니라 클래스도 템플릿화하여 일반화된 코드를 작성할 수 있습니다.
template<typename T>
class RandomBox {
public:
T GetRandomData() {
int idx = rand() % 10;
return _data[idx];
}
public:
T _data[10]; // 크기 10짜리 배열
};
int main() {
srand(static_cast<unsigned int>(time(nullptr)));
RandomBox<int> rb1;
for (int i = 0; i < 10; i++)
rb1._data[i] = i;
int value1 = rb1.GetRandomData();
cout << "랜덤 값 (int): " << value1 << endl;
RandomBox<float> rb2;
for (int i = 0; i < 10; i++)
rb2._data[i] = i + 0.5f;
float value2 = rb2.GetRandomData();
cout << "랜덤 값 (float): " << value2 << endl;
return 0;
}
template<typename T>를 사용하여 데이터 타입을 변경할 수 있는 클래스를 생성합니다.RandomBox<int> → int 타입의 데이터 저장.RandomBox<float> → float 타입의 데이터 저장.특정 타입에 대해 클래스 템플릿을 다르게 동작하도록 할 때 사용합니다.
template<typename T, int SIZE>
class RandomBox {
public:
T GetRandomData() {
int idx = rand() % SIZE;
return _data[idx];
}
public:
T _data[SIZE];
};
// 특수화: double 타입에 대해 별도로 정의
template<int SIZE>
class RandomBox<double, SIZE> {
public:
double GetRandomData() {
cout << "RandomBox double 특수화된 템플릿 호출" << endl;
int idx = rand() % SIZE;
return _data[idx];
}
public:
double _data[SIZE];
};
int main() {
RandomBox<int, 10> rb1;
RandomBox<double, 10> rb2;
cout << rb2.GetRandomData() << endl; // 특수화된 함수 호출
return 0;
}
template<typename T, int SIZE> 기본 템플릿을 정의합니다.template<int SIZE>로 double 타입에 대한 특수화를 진행합니다.RandomBox<double, 10>을 호출하면 특수화된 GetRandomData()가 실행됩니다.template<typename T>
class Container {
public:
Container(T value) : _value(value) {}
void PrintValue() {
cout << "저장된 값: " << _value << endl;
}
private:
T _value;
};
int main() {
Container<int> intContainer(10);
Container<string> strContainer("Hello Template");
intContainer.PrintValue();
strContainer.PrintValue();
return 0;
}
Container<int> 객체는 int 값을 저장.Container<string> 객체는 string 값을 저장.