Template Metaprogramming (TMP) คือเทคนิคการเขียนโปรแกรมที่ทำการคำนวณระหว่าง **compile-time** โดยใช้ template mechanism ของ C++ แทนที่จะคำนวณตอน runtime
หลักการทำงาน
- Template instantiation เกิดขึ้นที่ compile-time
- Compiler ทำ recursive template expansion
- ผลลัพธ์เป็นค่าคงที่ (constant) ที่พร้อมใช้งานตอน runtime
- เป็น Turing-complete (สามารถคำนวณอะไรก็ได้ที่คำนวณได้)
ตัวอย่างคลาสสิก: Power ของ 4
#include <iostream>
using namespace std;
// General case: 4^n = 4 * 4^(n-1)
template <int n>
struct Power4 {
static const int value = 4 * Power4<n - 1>::value;
};
// Base case: 4^0 = 1 (template specialization)
template <>
struct Power4<0> {
static const int value = 1;
};
int main() {
cout << "4^0 = " << Power4<0>::value << endl;
cout << "4^3 = " << Power4<3>::value << endl;
cout << "4^7 = " << Power4<7>::value << endl;
cout << "4^10 = " << Power4<10>::value << endl;
// ใช้เป็น array size (ต้องเป็น compile-time constant)
int arr[Power4<5>::value]; // int arr[1024];
cout << "Array size: " << sizeof(arr) / sizeof(int) << endl;
return 0;
}
ผลลัพธ์
4^0 = 1 4^3 = 64 4^7 = 16384 4^10 = 1048576 Array size: 1024
ตัวอย่างเพิ่มเติม: Factorial
template <int n>
struct Factorial {
static const long long value = n * Factorial<n - 1>::value;
};
template <>
struct Factorial<0> {
static const long long value = 1;
};
// ใช้งาน
cout << "5! = " << Factorial<5>::value << endl; // 120
cout << "10! = " << Factorial<10>::value << endl; // 3628800
Modern C++ (C++11 onwards): constexpr
แทนที่จะใช้ template metaprogramming แบบเก่า ให้ใช้ constexpr ซึ่งอ่านง่ายกว่าและรองรับ logic ซับซ้อนกว่า:
constexpr long long factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr long long power(int base, int exp) {
long long result = 1;
for (int i = 0; i < exp; ++i) result *= base;
return result;
}
int main() {
constexpr auto f5 = factorial(5); // คำนวณ compile-time
constexpr auto p7 = power(4, 7); // คำนวณ compile-time
int arr[factorial(4)]; // OK: compile-time constant
}
ข้อดี/ข้อเสียของ TMP
| ข้อดี | ข้อเสีย |
|---|---|
| Performance: ย้าย computation ไป compile-time | Compile time ช้าลง (template bloat) |
| Type safety: ตรวจสอบ type ที่ compile-time | Syntax ซับซ้อน ยากต่อการ debug |
| Flexibility: generic programming ขั้นสูง | Error messages ยาวและเข้าใจยาก |
| Zero runtime overhead | จำกัดได้แค่ integral types, types, templates |
กรณีใช้งานจริง
- Compile-time validation (static_assert)
- Type traits และ SFINAE
- Expression templates (เช่น Eigen, Blitz++)
- Dimension analysis (units library)
- Parser generators (Boost.Spirit)
สรุป
Template Metaprogramming เป็นเทคนิคขั้นสูงที่ย้ายการคำนวณไป compile-time ใน C++ สูงสุดควรใช้ constexpr และ consteval (C++20) แทน เพราะอ่านง่ายกว่าและมีความสามารถมากกว่า