ν νλ¦Ώ λ©ν νλ‘κ·Έλλ°μ λͺ¨λ κ²(Template Meta Programming)
ν νλ¦Ώ λ©ννλ‘κ·Έλλ° (Template Metaprogramming)
ν
νλ¦Ώ λ©ννλ‘κ·Έλλ°(Template Metaprogramming)μ C++μ κ°λ ₯ν ν
νλ¦Ώ μμ€ν
μ μ΄μ©νμ¬ μ»΄νμΌ νμμ μ½λμ μΌλΆλ₯Ό μμ±νκ±°λ κ³μ°νλ νλ‘κ·Έλλ° κΈ°λ²μ
λλ€. μ΄ κΈ°λ²μ C++μ ν
νλ¦Ώμ λ¨μν μ½λ μ¬μ¬μ© λκ΅¬λ‘ μ¬μ©νλ κ²μμ λ λμκ°, 볡μ‘ν κ³μ°μ΄λ 쑰건 μ²λ¦¬λ₯Ό μ»΄νμΌ μμ μ 미리 μννμ¬, μ€ν μμ μ μ±λ₯μ κ·Ήλνν μ μκ² ν©λλ€.
1. κΈ°λ³Έ κ°λ
ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ μΌλ°μ μΈ νλ‘κ·Έλλ° μΈμ΄μμμ μ€ν μμ (runtime) νλ‘κ·Έλλ°κ³Όλ λ€λ₯΄κ², νλ‘κ·Έλ¨μ΄ μ»΄νμΌλ λ μνλ©λλ€. μ΄λ νλ‘κ·Έλ¨μ΄ μ€νλκΈ° μ μ λ€μν μμ μ 미리 μννμ¬, μ€ν μμ μμλ μ΅λν ν¨μ¨μ μΈ μ½λλ§μ μ€νν μ μλλ‘ νλ κ²μ λͺ©νλ‘ ν©λλ€.
μ΄λ¬ν λ©ννλ‘κ·Έλλ°μ ν΅ν΄, μνμ κ³μ°, 쑰건 μ²λ¦¬, μ½λ μμ± λ±μ μ»΄νμΌ μμ μ μνν μ μμ΅λλ€.
- μ£Όμ νΉμ§:
- μ»΄νμΌ νμ κ³μ°: 볡μ‘ν κ³μ°μ΄λ λ Όλ¦¬λ₯Ό μ»΄νμΌ νμμ μνν μ μμ΅λλ€.
- μ½λ μμ±: μ€ν μμ μ λμ μΌλ‘ μμ±ν νμ μμ΄, μ»΄νμΌ νμμ νμν μ½λλ λ°μ΄ν°λ₯Ό μμ±ν μ μμ΅λλ€.
- μ±λ₯ μ΅μ ν: μ€ν μμ μ λΆλ΄μ μ€μ¬ νλ‘κ·Έλ¨μ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€.
- μ¬μ¬μ©μ±: ν
νλ¦Ώμ μ΄μ©ν μΌλ°νλ μ½λλ₯Ό μμ±ν¨μΌλ‘μ¨, μ¬μ¬μ©μ±κ³Ό νμ₯μ±μ λμΌ μ μμ΅λλ€.
2. μμ μ½λμ μ€λͺ
μμ 1: ν©ν λ¦¬μΌ κ³μ°
ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ μ¬μ©νμ¬ ν©ν 리μΌμ μ»΄νμΌ νμμ κ³μ°νλ μμ μ λλ€.
#include <iostream>
// κΈ°λ³Έ ν
νλ¦Ώ (μ¬κ· νΈμΆ)
template<int N>
struct Factorial {
static constexpr int value = N * Factorial<N - 1>::value;
};
// μ¬κ· μ’
λ£ μ‘°κ±΄ (N = 0)
template<>
struct Factorial<0> {
static constexpr int value = 1;
};
int main() {
std::cout << "Factorial of 5: " << Factorial<5>::value << std::endl; // Output: 120
return 0;
}
μ€λͺ :
- μ΄ μμ μμ Factorial ꡬ쑰체 ν νλ¦Ώμ μ¬κ·μ μΌλ‘ ν©ν 리μΌμ κ³μ°ν©λλ€. μλ₯Ό λ€μ΄, Factorial<5>λ 5 * Factorial<4>λ‘ νμ₯λ©λλ€.
- Factorial<0>μ κΈ°λ³Έ 쑰건μΌλ‘, μ¬κ· νΈμΆμ μ’ λ£νλ μν μ ν©λλ€.
- μ΅μ’
μ μΌλ‘, μ»΄νμΌ νμμ Factorial<5>::valueλ 120μΌλ‘ κ³μ°λ©λλ€.
μμ 2: μ»΄νμΌ νμμμ μ‘°κ±΄λΆ νμ μ ν
ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ μ¬μ©νμ¬ μ»΄νμΌ νμμ 쑰건μ λ°λΌ νμ μ μ ννλ μμ μ λλ€.
#include <iostream>
#include <type_traits>
// ν
νλ¦Ώ 쑰건μ λ°λΌ νμ
μ μ ννλ ꡬ쑰체
template<bool Condition, typename TrueType, typename FalseType>
struct Conditional {
using type = TrueType;
};
// νΉμν: μ‘°κ±΄μ΄ falseμΌ λ
template<typename TrueType, typename FalseType>
struct Conditional<false, TrueType, FalseType> {
using type = FalseType;
};
int main() {
using SelectedType = Conditional<(sizeof(int) > 4), double, int>::type;
if constexpr (std::is_same_v<SelectedType, double>) {
std::cout << "Selected type is double." << std::endl;
} else {
std::cout << "Selected type is int." << std::endl;
}
return 0;
}
μ€λͺ :
- Conditional ꡬ쑰체λ μ£Όμ΄μ§ 쑰건(μ»΄νμΌ νμ 쑰건)μ λ°λΌ TrueType λλ FalseType μ€ νλλ₯Ό μ νν©λλ€.
- μ΄ μμ μμλ sizeof(int) > 4λΌλ 쑰건μ ν΅ν΄ SelectedTypeμ΄ doubleμΈμ§ intμΈμ§λ₯Ό κ²°μ ν©λλ€.
- if constexprμ μ¬μ©νμ¬ μ νλ νμ
μ λ°λΌ λ€λ₯Έ μ½λλ₯Ό μ€νν μ μμ΅λλ€.
μμ 3: μ»΄νμΌ νμμμ μ κ³± κ³μ°
ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ μ¬μ©νμ¬ μ«μμ μ κ³±μ μ»΄νμΌ νμμ κ³μ°νλ μμ μ λλ€.
#include <iostream>
// κΈ°λ³Έ ν
νλ¦Ώ (μ¬κ· νΈμΆ)
template<int N, int Power>
struct PowerOf {
static constexpr int value = N * PowerOf<N, Power - 1>::value;
};
// μ¬κ· μ’
λ£ μ‘°κ±΄ (Power = 0)
template<int N>
struct PowerOf<N, 0> {
static constexpr int value = 1;
};
int main() {
std::cout << "2^4: " << PowerOf<2, 4>::value << std::endl; // Output: 16
return 0;
}
μ€λͺ :
- PowerOf ꡬ쑰체 ν νλ¦Ώμ μ¬κ·μ μΌλ‘ μ«μμ μ κ³±μ κ³μ°ν©λλ€.
- PowerOf<N, 0>μ κΈ°λ³Έ 쑰건μΌλ‘, μ¬κ· νΈμΆμ μ’ λ£νλ μν μ ν©λλ€.
- μ»΄νμΌ νμμ PowerOf<2, 4>::valueλ 16μΌλ‘ κ³μ°λ©λλ€.
3. ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ μ₯λ¨μ
μ₯μ :
- μ»΄νμΌ νμ μ΅μ ν: 볡μ‘ν κ³μ°μ μ€ν μμ μ΄ μλ μ»΄νμΌ μμ μ μνν μ μμ΄ μ±λ₯μ΄ ν₯μλ©λλ€.
- νμ μμ μ±: ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ κ°λ ₯ν νμ κ²μ¬λ₯Ό μ 곡νμ¬, μ½λμ μμ μ±μ λμ λλ€.
- μ½λ μ¬μ¬μ©μ±: μΌλ°νλ μ½λλ₯Ό μμ±ν μ μμ΄, λ€μν μν©μ λ§κ² μ¬μ¬μ©ν μ μμ΅λλ€.
λ¨μ :
- 볡μ‘μ±: ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ λ§€μ° λ³΅μ‘ν μ μμΌλ©°, μ΄ν΄νκΈ° μ΄λ €μ΄ μλ¬ λ©μμ§λ₯Ό μ΄λν μ μμ΅λλ€.
- μ»΄νμΌ μκ° μ¦κ°: 볡μ‘ν λ©ννλ‘κ·Έλλ°μ μ»΄νμΌ μκ°μ μ¦κ°μν¬ μ μμ΅λλ€.
- λλ²κΉ
μ΄λ €μ: μ»΄νμΌ νμμ μ€νλλ μ½λμ΄κΈ° λλ¬Έμ, λλ²κΉ
μ΄ λ§€μ° μ΄λ ΅μ΅λλ€.
4. νμ© μ¬λ‘
- κ³ κΈ λΌμ΄λΈλ¬λ¦¬ κ°λ°: ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ κ³ κΈ C++ λΌμ΄λΈλ¬λ¦¬(μ: Boost, Eigen, MPL)μμ μμ£Ό μ¬μ©λ©λλ€.
- μ»΄νμΌ νμ κ³μ°: μνμ κ³μ°μ΄λ μμ μμ±μ μ¬μ©λ©λλ€.
- μ μ λ€νμ± κ΅¬ν: λ°νμ λ€νμ± λμ μ»΄νμΌ νμμ λ€νμ±μ ꡬνν μ μμ΅λλ€.
- μ μ κ²μ¬: μ»΄νμΌ νμμ νμ μ΄λ 쑰건μ κ²μ¦νλ λ° μ¬μ©λ©λλ€.
ν νλ¦Ώ λ©ννλ‘κ·Έλλ°μ C++μ κ°λ ₯ν κΈ°λ₯ μ€ νλλ‘, κ³ κΈ C++ νλ‘κ·Έλλ°μμ νμμ μΈ λꡬμ λλ€. μ΄λ₯Ό ν΅ν΄ μ»΄νμΌ νμμ μ½λμ μ΅μ νμ μμ μ±μ 보μ₯ν μ μμΌλ©°, 볡μ‘ν λ¬Έμ λ₯Ό ν΄κ²°νλ λ° λ§€μ° μ μ©ν©λλ€.