C++ Template Metaprogramming: Derleme Zamanında Hesaplama
Template metaprogramming (TMP), C++'ın en güçlü özelliklerinden biri. Derleyiciye derleme zamanında kod yazmasını sağlayarak runtime performansını muazzam ölçüde artırırsın. Sıfır overhead abstraction yaratabilirsin, yani güvenli, okunaklı kod yazarken makine kodu hızında çalışır.
Tasarım basit: şablonları özyinelemeli olarak özelleştir, base case'e ulaşana kadar. Derleyici her adımda yeni bir fonksiyon/sınıf türetir. Sonuç? Tüm hesaplamalar derleme sırasında biter, runtime'da sadece sabit değer kalır.
Faktöriyeli derleme zamanında hesaplayalım:
1#include <iostream>23template<int N>4struct Factorial {5static constexpr int value = N * Factorial<N - 1>::value;6};78template<>9struct Factorial<0> {10static constexpr int value = 1;11};1213int main() {14constexpr int result = Factorial<5>::value;15std::cout << "5! = " << result << std::endl;16return 0;17}Beklenen çıktı: `5! = 120`
Derleyici Factorial<5>, Factorial<4>, Factorial<3>... şeklinde zincirleme oluşturur. Derleme bittiğinde `result` zaten 120 olarak sabitlenmiştir. Runtime'da hiçbir hesaplama olmaz.
Fibonacci'yi daha karmaşık bir örnekle görelim:
1#include <iostream>23template<int N>4struct Fibonacci {5static constexpr int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;6};78template<>9struct Fibonacci<0> {10static constexpr int value = 0;11};1213template<>14struct Fibonacci<1> {15static constexpr int value = 1;16};1718int main() {19constexpr int fib10 = Fibonacci<10>::value;20std::cout << "Fibonacci(10) = " << fib10 << std::endl;21return 0;22}Beklenen çıktı: `Fibonacci(10) = 55`
Tip kontrollü bir örnek de ekleyelim, TMP sadece sayı hesaplaması değildir. Derleyiciye hangi tipler uyumlu olduğunu söyleyebilirsin:
1#include <iostream>2#include <type_traits>34template<typename T>5struct IsInteger: std::false_type {};67template<>8struct IsInteger<int>: std::true_type {};910template<>11struct IsInteger<long>: std::true_type {};1213int main() {14std::cout << std::boolalpha;15std::cout << "int is integer: " << IsInteger<int>::value << std::endl;16std::cout << "double is integer: " << IsInteger<double>::value << std::endl;17return 0;18}Beklenen çıktı:
1int is integer: true2double is integer: falseSık yapılan hata: derleyici özyinelemeli şablonları sınırsız açabilir. Fibonacci örneğinde Fibonacci<10> çok sayıda aynı hesaplamayı tekrarlar. Büyük sayılar için derleme süresi ve binary boyutu artar. Memoization veya iteratif şablonlar bu sorunu çözer.
C++20 ile `if constexpr` ve `consteval` geliştirmeleri, TMP'yi daha okunabilir hale getirdi. Ama temel mantık aynı: derleyiciye çalışmasını ver, runtime'da sadece sonuçları kullan.
0 yorum