C++ STL: 8장 - STL과 고급 템플릿 기법
2025. 2. 26. 18:17ㆍ프로그래밍 언어/C++ STL
8.1 템플릿의 기본 개념
템플릿은 일반화 프로그래밍(generic programming)을 지원하기 위해 C++에서 제공하는 강력한 기능입니다. STL은 템플릿을 기반으로 설계되어, 컨테이너, 알고리즘, 반복자 등이 다양한 데이터 타입에서 동작할 수 있도록 일반화되어 있습니다.
8.1.1 함수 템플릿
- 다양한 타입의 데이터를 처리하는 함수 작성에 사용됩니다.
예제:
#include <iostream>
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << add(5, 3) << "\n"; // 정수
std::cout << add(5.5, 2.5) << "\n"; // 실수
return 0;
}
8.1.2 클래스 템플릿
- 데이터 타입에 의존하지 않는 클래스 작성에 사용됩니다.
예제:
#include <iostream>
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
void display() { std::cout << value << "\n"; }
};
int main() {
Box<int> intBox(123);
Box<std::string> strBox("Hello");
intBox.display();
strBox.display();
return 0;
}
8.2 템플릿 특수화
템플릿 특수화는 특정 타입에 대해 일반 템플릿과는 다른 동작을 정의할 때 사용됩니다.
8.2.1 함수 템플릿 특수화
- 특정 타입에 대해 별도의 구현을 제공합니다.
예제:
#include <iostream>
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 함수 템플릿 특수화 (const char* 타입)
template <>
const char* max(const char* a, const char* b) {
return (std::strcmp(a, b) > 0) ? a : b;
}
int main() {
std::cout << max(10, 20) << "\n"; // 정수
std::cout << max("apple", "banana") << "\n"; // 문자열
return 0;
}
8.2.2 클래스 템플릿 특수화
- 특정 타입에 대해 별도의 클래스 정의를 제공합니다.
예제:
#include <iostream>
template <typename T>
class Printer {
public:
void print(T value) { std::cout << value << "\n"; }
};
// 클래스 템플릿 특수화 (bool 타입)
template <>
class Printer<bool> {
public:
void print(bool value) {
std::cout << (value ? "true" : "false") << "\n";
}
};
int main() {
Printer<int> intPrinter;
Printer<bool> boolPrinter;
intPrinter.print(123);
boolPrinter.print(true);
return 0;
}
8.3 가변 길이 템플릿 (Variadic Templates)
C++11부터 도입된 가변 길이 템플릿은 임의의 개수의 인자를 처리할 수 있는 템플릿 작성에 유용합니다.
8.3.1 가변 길이 함수 템플릿
예제:
#include <iostream>
template <typename... Args>
void printAll(Args... args) {
(std::cout << ... << args) << "\n"; // Fold expression
}
int main() {
printAll(1, 2, 3.5, "Hello", true);
return 0;
}
8.3.2 가변 길이 클래스 템플릿
예제:
#include <iostream>
#include <tuple>
template <typename... Args>
class MultiContainer {
private:
std::tuple<Args...> data;
public:
MultiContainer(Args... args) : data(args...) {}
void print() { std::apply([](auto&&... args) { ((std::cout << args << " "), ...); }, data); }
};
int main() {
MultiContainer<int, double, std::string> container(1, 2.5, "Hello");
container.print();
return 0;
}
8.4 템플릿 메타프로그래밍 (Template Metaprogramming)
템플릿 메타프로그래밍은 컴파일 타임에 코드를 생성하거나 계산을 수행하는 고급 기법입니다. STL의 일부 구성 요소는 이러한 기법을 사용해 설계되었습니다.
8.4.1 기본 템플릿 재귀
예제:
#include <iostream>
template <int N>
struct Factorial {
static constexpr int value = N * Factorial<N - 1>::value;
};
template <>
struct Factorial<0> {
static constexpr int value = 1;
};
int main() {
std::cout << "Factorial of 5: " << Factorial<5>::value << "\n";
return 0;
}
Note: 위 예제는 컴파일 타임 계산을 보여주는 데 유용하지만, 큰 값에 대해 사용하면 컴파일러의 재귀 제한에 걸릴 수 있습니다. 따라서 적절한 크기에서 사용하는 것이 중요합니다.
8.4.2 std::enable_if를 활용한 SFINAE
- SFINAE(Substitution Failure Is Not An Error)를 사용하여 특정 조건에 따라 템플릿 활성화 여부를 결정합니다.
- SFINAE는 템플릿 인자에 대한 조건을 기반으로 유효하지 않은 템플릿 인자를 무시하는 메커니즘입니다.
예제:
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
increment(T value) {
return value + 1;
}
int main() {
std::cout << increment(5) << "\n"; // 정수는 허용
// std::cout << increment(5.5) << "\n"; // 컴파일 에러
return 0;
}
Note: std::enable_if를 사용하면 템플릿의 유효성을 조건부로 제어할 수 있습니다. C++20에서는 std::enable_if 대신 concepts를 활용해 더 간단하고 명확하게 조건을 정의할 수 있습니다.
8.5 STL에서 템플릿 기법 활용
8.5.1 STL 컨테이너의 템플릿 사용
- STL 컨테이너는 대부분 템플릿 클래스로 설계되어 있습니다.
- 예: std::vector<T>, std::map<Key, Value>.
8.5.2 STL 알고리즘과 템플릿
- STL 알고리즘은 템플릿 함수로 설계되어, 어떤 컨테이너 타입에도 적용 가능합니다.
예제:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5};
std::sort(vec.begin(), vec.end());
for (int n : vec) {
std::cout << n << " ";
}
return 0;
}
결론
템플릿은 C++의 강력한 기능 중 하나로, STL의 근간을 이루고 있습니다. 기본 템플릿부터 고급 기법인 가변 길이 템플릿, 메타프로그래밍까지 이해한다면, 더욱 효율적이고 유연한 코드를 작성할 수 있습니다.
'프로그래밍 언어 > C++ STL' 카테고리의 다른 글
C++ STL: 10장 - STL의 한계와 대안 (0) | 2025.02.26 |
---|---|
C++ STL: 9장 - STL 내부 구현 심화 (0) | 2025.02.26 |
C++ STL: 7장 - STL과 멀티스레딩 활용 (0) | 2025.02.26 |
C++ STL: 6장 - STL 컨테이너 성능 비교와 활용 사례 (0) | 2025.02.26 |
C++ STL: 5장 - STL과 메모리 관리 (0) | 2025.02.26 |