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 <iostream>
2
3template<int N>
4struct Factorial {
5static constexpr int value = N * Factorial<N - 1>::value;
6};
7
8template<>
9struct Factorial<0> {
10static constexpr int value = 1;
11};
12
13int 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:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1 <iostream>
2
3template<int N>
4struct Fibonacci {
5static constexpr int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
6};
7
8template<>
9struct Fibonacci<0> {
10static constexpr int value = 0;
11};
12
13template<>
14struct Fibonacci<1> {
15static constexpr int value = 1;
16};
17
18int 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 <iostream>
2 <type_traits>
3
4template<typename T>
5struct IsInteger: std::false_type {};
6
7template<>
8struct IsInteger<int>: std::true_type {};
9
10template<>
11struct IsInteger<long>: std::true_type {};
12
13int 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: true
2double is integer: false

Sı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.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz