C++ 템플릿 완전 정복
1. 함수 템플릿
함수 템플릿은 하나의 함수 정의로 여러 타입의 데이터를 처리할 수 있도록 해주는 C++의 기능입니다.
이를 통해 코드 중복을 줄이고, 다양한 데이터 타입에 대해 동일한 로직을 재사용할 수 있습니다.
#include <iostream>
using namespace std;
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
cout << add(10, 20) << endl; // int
cout << add(1.5, 2.3) << endl; // double
cout << add(string("Hello, "), string("World!")) << endl; // string
return 0;
}
📌 Tip: `T`는 템플릿 인자이며, 함수 호출 시 실제 전달된 타입에 따라 자동으로 결정됩니다.
2. 클래스 템플릿
클래스 템플릿은 하나의 클래스 정의를 바탕으로 다양한 타입의 객체를 생성할 수 있게 해줍니다.
예를 들어 int형을 저장하는 박스와 string형을 저장하는 박스를 같은 클래스 템플릿으로 만들 수 있습니다.
#include <iostream>
using namespace std;
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() {
return value;
}
};
int main() {
Box<int> intBox(100);
Box<string> strBox("템플릿");
cout << intBox.getValue() << endl;
cout << strBox.getValue() << endl;
return 0;
}
📌 Tip: 클래스 템플릿은 객체 생성 시 타입을 명시적으로 지정해야 합니다.
3. 템플릿 특수화
템플릿 특수화는 특정 데이터 타입에 대해 템플릿의 동작을 커스터마이징하는 기능입니다.
일반적인 템플릿 정의 외에도 특정 타입에 대해 별도의 구현을 제공할 수 있어, 성능을 개선하거나 로직을 변경할 수 있습니다.
#include <iostream>
using namespace std;
template <typename T>
void print(T val) {
cout << "일반: " << val << endl;
}
// 특수화: char 타입
template <>
void print<char>(char val) {
cout << "문자: " << val << endl;
}
int main() {
print(123); // 일반
print(3.14); // 일반
print('A'); // 특수화
return 0;
}
📌 Tip: 특수화를 통해 특정 타입에 최적화된 동작을 구현할 수 있습니다.
4. 템플릿과 타입 추론
함수 템플릿은 컴파일러가 인자의 타입을 자동으로 추론하므로, 호출 시 타입을 명시하지 않아도 됩니다.
그러나 클래스 템플릿은 명시적으로 타입을 지정해야 합니다(C++17 이후에는 추론 가능).
template <typename T, typename U>
auto multiply(T a, U b) {
return a * b;
}
int main() {
cout << multiply(2, 3.5) << endl; // double로 추론
}
📌 Tip: auto 키워드와 함께 사용하면 반환형도 유연하게 처리할 수 있습니다.
5. 템플릿의 한계와 주의점
템플릿은 매우 강력한 기능이지만 몇 가지 주의점이 있습니다.
- 컴파일 타임에 타입을 결정하므로, 컴파일 시간이 길어질 수 있습니다.
- 템플릿 에러 메시지는 매우 복잡하고 장황할 수 있어 디버깅이 어렵습니다.
- 모든 코드는 인스턴스화 시 생성되므로, 코드 크기가 커질 수 있습니다.
⚠️ 주의: 템플릿은 필요한 경우에만 사용하고, 지나친 일반화는 오히려 유지보수를 어렵게 만들 수 있습니다.
마무리
템플릿은 C++의 가장 유연하고 강력한 기능 중 하나입니다. 동일한 알고리즘을 다양한 타입에 적용할 수 있도록 하여 코드 재사용성을 높이고, 유지보수를 수월하게 만듭니다.
함수 템플릿과 클래스 템플릿을 적절히 활용하고, 특정 타입에 대해 특수화를 적용한다면 보다 안정적이고 효율적인 코드를 작성할 수 있습니다.