C++ 프로그래밍을 하다 보면 자료형(int, double 등)만 다르고 로직은 완전히 같은 함수를 여러 개 만들어야 할 때가 있습니다. 이때 우리를 구원해 주는 기능이 바로 템플릿(Template)입니다. 템플릿은 제네릭 프로그래밍(Generic Programming)을 가능하게 하여 코드의 재사용성을 극대화합니다.
오늘은 C++ 템플릿의 기초부터 고급 기법인 특수화까지, 예제와 함께 자세히 알아보겠습니다.

1. 템플릿(Template)이란?
템플릿은 특정 타입에 얽매이지 않는 '코드의 설계도'입니다. 컴파일 시점에 사용자가 전달한 타입에 맞춰 실제 코드가 생성(인스턴스화)되므로, 하나의 코드로 다양한 타입을 처리할 수 있습니다.
2. 함수 템플릿 (Function Template)
함수 템플릿은 함수의 매개변수나 반환 타입을 일반화합니다.
#include <iostream>
// T는 어떤 타입이든 될 수 있는 템플릿 매개변수입니다.
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
// 컴파일러가 인자를 보고 타입을 자동으로 유추합니다.
std::cout << "정수 합: " << add(10, 20) << std::endl; // T는 int
std::cout << "실수 합: " << add(1.2, 3.4) << std::endl; // T는 double
return 0;
}
3. 클래스 템플릿 (Class Template)
데이터 구조(Stack, Queue, Vector 등)를 만들 때 특정 타입에 의존하지 않도록 설계할 수 있습니다.
예제: 범용 Stack 구현
#include <iostream>
#include <vector>
#include <string>
template <typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(T const& element) { elements.push_back(element); }
void pop() { if (!elements.empty()) elements.pop_back(); }
T top() const { return elements.back(); }
};
int main() {
Stack<int> intStack; // 정수형 스택
Stack<std::string> strStack; // 문자열 스택
intStack.push(100);
strStack.push("C++ Template");
std::cout << intStack.top() << " / " << strStack.top() << std::endl;
return 0;
}
4. 비타입(Non-type) 템플릿 매개변수
템플릿에는 int나 double 같은 타입뿐만 아니라, 정수 상수를 직접 전달할 수도 있습니다. 이는 컴파일 타임에 크기가 결정되어야 하는 고정 배열 등에 유용합니다.
template <typename T, int Size>
class StaticArray {
private:
T data[Size]; // 컴파일 타임에 배열 크기가 결정됨
public:
int getSize() { return Size; }
};
int main() {
StaticArray<int, 5> myArr; // 크기가 5인 정수 배열 객체 생성
return 0;
}
5. 템플릿 특수화 (Template Specialization)
특정 타입에 대해서만 다르게 동작해야 할 때 사용합니다. 예를 들어, bool 타입이나 char* 타입은 일반적인 로직과 다르게 처리해야 할 때가 많습니다.
// 일반 템플릿
template <typename T>
class Formatter {
public:
void print(T val) { std::cout << "Value: " << val << std::endl; }
};
// std::string 타입에 대한 특수화
template <>
class Formatter<std::string> {
public:
void print(std::string val) { std::cout << "String: [" << val << "]" << std::endl; }
};
6. 템플릿 사용 시 주의사항 (수익형 블로그 팁)
템플릿은 강력하지만 사용 시 주의해야 할 단점도 명확합니다. 이 부분을 포스팅에 포함하면 전문성이 높아집니다.
- 컴파일 시간 증가: 컴파일러가 각 타입에 맞는 코드를 새로 생성하므로 빌드 시간이 길어질 수 있습니다.
- 코드 비대화(Code Bloat): 사용하는 타입이 많아질수록 실행 파일의 크기가 커질 수 있습니다. (임베디드 환경에서는 특히 주의!)
- 선언과 구현의 분리 문제: 템플릿은 컴파일러가 타입을 알아야 코드를 생성할 수 있으므로, 보통 헤더 파일(.h)에 구현부까지 포함해야 합니다.
결론
C++ 템플릿은 현대적인 C++ 개발에서 빼놓을 수 없는 핵심 도구입니다. STL(Standard Template Library)의 근간이 되는 기술이기도 하죠. 처음에는 문법이 생소할 수 있지만, 한 번 익혀두면 코드의 질이 달라집니다.
오늘 배운 함수 템플릿과 클래스 템플릿을 여러분의 프로젝트에 적용하여 중복 코드를 획기적으로 줄여보세요!
'Core Programming > Modern C++ & System Design' 카테고리의 다른 글
| C++ 예외 처리 완벽 가이드: try-catch-throw 문법과 실전 예제 (0) | 2024.12.20 |
|---|---|
| C++ STL 총정리: 컨테이너, 반복자, 알고리즘 핵심 요약 및 예제 (0) | 2024.12.20 |
| C++ 네임스페이스(Namespace) 사용법 총정리: 이름 충돌 방지와 모듈화 (0) | 2024.12.20 |
| C++ 연산자 오버로딩 완벽 정리: 복소수 예제로 배우는 연산자 재정의 (0) | 2024.12.19 |
| C++ 상속과 다형성 완벽 가이드: 가상 함수와 추상 클래스 활용법 (0) | 2024.12.19 |