C++의 강력한 코드 재사용 도구인 템플릿(Template)에 대해 학습했다. 템플릿을 사용하면 int, double, string 등 다양한 자료형에 대해 동작하는 일반화된 함수나 클래스를 한 번만 정의하여 사용할 수 있다는 것을 배웠다. 🔥 이를 통해 타입별로 여러 개의 함수를 만들어야 했던 함수 오버로딩의 번거로움을 해결하고, 코드의 중복을 줄여 생산성과 유지보수성을 크게 향상시키는 방법을 익혔다. 💻
int를 더하는 add, double을 더하는 add 함수를 각각 만들어야 한다.char -> int, float -> double)이 가능한 함수를 찾는다.double -> int)이 가능한 함수를 찾는다.template <typename T> 또는 template <class T> 키워드를 함수 정의 앞에 붙여 사용한다. 여기서 T는 "타입 매개변수"로, 실제 함수 호출 시 컴파일러가 인자의 타입을 보고 T를 구체적인 타입(int, double 등)으로 대체하여 코드를 생성한다.template <typename T>를 붙여 선언한다.Array<int> arr; 와 같이 <> 안에 사용할 타입을 명시적으로 지정해주어야 한다.add 함수#include <iostream>
#include <string>
// 각 타입에 맞춰 개별적으로 함수를 정의해야 함
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
std::string add(const std::string& a, const std::string& b) {
return a + b;
}
add 함수#include <iostream>
#include <string>
// template 키워드를 사용하여 하나의 일반화된 함수를 정의
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
// 컴파일러가 인자를 보고 T를 각 타입(int, double, string)으로 추론하여 코드를 생성
std::cout << "3 + 5 = " << add(3, 5) << std::endl;
std::cout << "2.5 + 4.3 = " << add(2.5, 4.3) << std::endl;
std::cout << "Hello + World = " << add(std::string("Hello"), std::string("World")) << std::endl;
return 0;
}
#include <iostream>
// 어떤 타입(T)의 데이터든 저장할 수 있는 일반화된 Array 클래스
template <typename T>
class Array {
private:
T data[100]; // T 타입의 데이터를 저장할 배열
int size;
public:
Array() : size(0) {}
void add(const T& element) {
if (size < 100) {
data[size++] = element;
}
}
void print() const {
for (int i = 0; i < size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
};
int main() {
// int 타입을 저장하는 Array 객체 생성
Array<int> intArray;
intArray.add(10);
intArray.add(20);
std::cout << "Int Array: ";
intArray.print();
// double 타입을 저장하는 Array 객체 생성
Array<double> doubleArray;
doubleArray.add(3.14);
doubleArray.add(2.71);
std::cout << "Double Array: ";
doubleArray.print();
return 0;
}
Array arr; 와 같이 타입을 명시하지 않고 사용하려다 오류를 겪었다. 클래스 템플릿은 함수 템플릿과 달리 컴파일러가 타입을 자동으로 추론해주지 않으므로, Array<int> arr; 처럼 사용할 타입을 <> 안에 명시적으로 지정해야 한다는 것을 배웠다.template <typename T>를 선언하고 나서, 함수나 클래스 내부에서 T 대신 무심코 int 같은 구체적인 타입을 써서 템플릿의 의미를 무색하게 만드는 실수를 했다. 템플릿을 사용하기로 했으면, 일반화가 필요한 모든 곳에 타입 매개변수(T)를 일관되게 사용해야 한다.| 개념 | 설명 | 비고 |
|---|---|---|
| 함수 오버로딩 | 이름은 같지만 매개변수의 타입이나 개수가 다른 함수를 여러 개 정의하는 것. | 반환 타입만 다른 것은 불가. |
| 템플릿 (Template) | 타입에 독립적인 일반화된 코드를 작성하게 해주는 C++ 기능. | 코드 재사용성 극대화. |
template <typename T> | "어떤 타입이든 올 수 있으며, 그 타입을 지금부터 T라고 부르겠다"는 선언. | typename 대신 class도 사용 가능. |
| 함수 템플릿 | 다양한 타입에 대해 동작하는 하나의 함수를 정의. 컴파일러가 호출 시 타입을 추론한다. | add<int>(3, 5)처럼 명시적 호출도 가능. |
| 클래스 템플릿 | 다양한 타입을 멤버로 가질 수 있는 하나의 클래스를 정의. 객체 생성 시 타입을 명시해야 한다. | MyClass<int> obj; |