템플릿은 C++의 강력한 기능으로, 코드의 재사용성을 높이고 일반화된 프로그래밍을 가능하게 합니다. 오늘은 템플릿 프로그래밍의 고급 개념들을 다루겠습니다.
템플릿 특수화 (Template Specialization)
템플릿 특수화는 특정 타입에 대해 템플릿을 특수화하여 다르게 동작하도록 하는 방법입니다. 템플릿 특수화는 주로 기본 템플릿이 특정 타입에 대해 적합하지 않을 때 사용됩니다.
기본 템플릿
#include <iostream>
template <typename T>
class MyClass {
public:
void display() {
std::cout << "Generic template" << std::endl;
}
};
특수화 템플릿
template <>
class MyClass<int> {
public:
void display() {
std::cout << "Specialized template for int" << std::endl;
}
};
int main() {
MyClass<double> obj1;
obj1.display(); // Generic template
MyClass<int> obj2;
obj2.display(); // Specialized template for int
return 0;
}
위의 코드에서 MyClass<int>
는 int
타입에 대해 특수화된 템플릿을 사용합니다.
부분 특수화 (Partial Specialization)
부분 특수화는 템플릿 매개변수의 일부에 대해 특수화하는 방법입니다. 주로 클래스 템플릿에서 사용됩니다.
기본 템플릿
#include <iostream>
template <typename T, typename U>
class MyPair {
public:
void display() {
std::cout << "Generic template" << std::endl;
}
};
부분 특수화
template <typename T>
class MyPair<T, int> {
public:
void display() {
std::cout << "Partially specialized template for int" << std::endl;
}
};
int main() {
MyPair<double, double> obj1;
obj1.display(); // Generic template
MyPair<double, int> obj2;
obj2.display(); // Partially specialized template for int
return 0;
}
위의 코드에서 MyPair<T, int>
는 두 번째 템플릿 매개변수가 int
일 때 부분 특수화된 템플릿을 사용합니다.
템플릿 메타프로그래밍 (Template Metaprogramming)
템플릿 메타프로그래밍은 컴파일 시간에 실행되는 코드를 작성하는 기법입니다. 주로 상수 표현식과 컴파일 시간 계산에 사용됩니다.
팩토리얼 계산 예제
#include <iostream>
// 기본 템플릿
template <int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};
// 특수화 템플릿
template <>
struct Factorial<0> {
static const int value = 1;
};
int main() {
std::cout << "Factorial<5>::value = " << Factorial<5>::value << std::endl; // 120
std::cout << "Factorial<10>::value = " << Factorial<10>::value << std::endl; // 3628800
return 0;
}
위의 코드에서 Factorial<N>
템플릿은 컴파일 시간에 팩토리얼 값을 계산합니다.
가변 인자 템플릿 (Variadic Templates)
가변 인자 템플릿은 임의의 개수의 템플릿 매개변수를 처리할 수 있습니다. C++11부터 도입된 이 기능은 템플릿 함수나 클래스를 더욱 유연하게 만듭니다.
기본 가변 인자 템플릿
#include <iostream>
// 기본 템플릿
template <typename... Args>
void print(Args... args) {
(std::cout << ... << args) << std::endl; // Fold expression (C++17)
}
int main() {
print(1, 2, 3.5, "Hello"); // 1 2 3.5 Hello
return 0;
}
위의 코드에서 print
함수는 가변 인자를 받아 출력합니다. C++17의 폴드 표현식을 사용하여 가변 인자 템플릿을 처리합니다.
실습 문제
문제 1: 부분 특수화를 사용하여 특정 타입에 대해 다르게 동작하는 클래스 작성
기본적으로 두 개의 값을 저장하는 템플릿 클래스를 작성하되, 두 번째 타입이 char
일 경우 해당 타입을 다르게 처리하도록 부분 특수화하세요.
해설:
#include <iostream>
// 기본 템플릿
template <typename T, typename U>
class MyPair {
public:
T first;
U second;
MyPair(T f, U s) : first(f), second(s) {}
void display() {
std::cout << "Generic template: " << first << ", " << second << std::endl;
}
};
// 부분 특수화
template <typename T>
class MyPair<T, char> {
public:
T first;
char second;
MyPair(T f, char s) : first(f), second(s) {}
void display() {
std::cout << "Partially specialized template for char: " << first << ", " << second << std::endl;
}
};
int main() {
MyPair<int, double> obj1(1, 2.5);
obj1.display(); // Generic template: 1, 2.5
MyPair<int, char> obj2(1, 'A');
obj2.display(); // Partially specialized template for char: 1, A
return 0;
}
문제 2: 템플릿 메타프로그래밍을 사용하여 피보나치 수열 계산
템플릿 메타프로그래밍을 사용하여 컴파일 시간에 피보나치 수열의 값을 계산하는 템플릿을 작성하세요.
해설:
#include <iostream>
// 기본 템플릿
template <int N>
struct Fibonacci {
static const int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
};
// 특수화 템플릿
template <>
struct Fibonacci<0> {
static const int value = 0;
};
template <>
struct Fibonacci<1> {
static const int value = 1;
};
int main() {
std::cout << "Fibonacci<10>::value = " << Fibonacci<10>::value << std::endl; // 55
std::cout << "Fibonacci<15>::value = " << Fibonacci<15>::value << std::endl; // 610
return 0;
}
문제 3: 가변 인자 템플릿을 사용하여 여러 인자를 받아 출력하는 함수 작성
가변 인자 템플릿을 사용하여 임의의 개수의 인자를 받아 출력하는 함수를 작성하세요.
해설:
#include <iostream>
// 기본 템플릿
template <typename... Args>
void print(Args... args) {
(std::cout << ... << args) << std::endl; // Fold expression (C++17)
}
int main() {
print(1, 2, 3.5, "Hello"); // 1 2 3.5 Hello
print("A", "B", "C"); // ABC
return 0;
}
이제 2일차의 학습을 마쳤습니다. 템플릿 특수화, 부분 특수화, 템플릿 메타프로그래밍, 가변 인자 템플릿에 대해 상세히 학습하고 실습 문제를 풀어보았습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "SFINAE와 개념"에 대해 다루겠습니다.
'-----ETC----- > C++ 고급 프로그래밍과 응용 프로젝트 시리즈' 카테고리의 다른 글
[C++ 고급 프로그래밍과 응용 프로젝트 시리즈] Day 6: constexpr과 상수 표현식 (0) | 2024.08.01 |
---|---|
[C++ 고급 프로그래밍과 응용 프로젝트] Day 3: SFINAE와 개념 (0) | 2024.08.01 |
[C++ 고급 프로그래밍과 응용 프로젝트 시리즈] Day 4: C++20의 개념과 모듈 (0) | 2024.08.01 |
[C++ 고급 프로그래밍과 응용 프로젝트] Day 1: 람다 함수와 함수 객체 (0) | 2024.08.01 |
[C++ 고급 프로그래밍과 응용] 목차 (0) | 2024.06.20 |