Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Template Metaprogramming ใน C++: การคำนวณที่ Compile-time

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-timeCompile time ช้าลง (template bloat)
Type safety: ตรวจสอบ type ที่ compile-timeSyntax ซับซ้อน ยากต่อการ 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) แทน เพราะอ่านง่ายกว่าและมีความสามารถมากกว่า