Konunun Tarihi
C++ başlangıçta yalnızca makroları (#define) ve sabitleri (const) destekliyordu. Ancak derleme zamanında değerleri belirlemek için bu yeterli değildi. C++11 ile birlikte, ifade değerlerinin yalnızca programın çalışma zamanında değil, derleme aşamasında da hesaplanmasına izin veren constexpr anahtar kelimesi tanıtıldı.
Sorun
constexpr gelmeden önce birçok görev ya makrolar (tip güvenliği olmayan kaba metin yerleştirici) ya da derleme aşamasında ifade hesaplamasının her zaman garanti edilmediği const kullanılarak çözülüyordu. Bu nedenle programın optimizasyonu zorlaşıyor ve daha az öngörülebilir bir davranış sergiliyordu.
Çözüm
constexpr, bildirilen ifadenin derleme sırasında hesaplanacağının garantisini verir, eğer mümkünse. Bu, derleme sırasında güvenli ve etkili bir şekilde hesaplanabilen sınıf yöntem ve yapıcıları da dahil olmak üzere, fonksiyonlar ve değişkenler bildirimi için kullanılır.
Kod örneği:
constexpr int Square(int x) { return x * x; } constexpr int size = Square(5); // size derleme zamanında hesaplanır const int arr[size] = {}; // dizi boyutu olarak kullanılabilir
Ana özellikler:
Herhangi bir fonksiyonu constexpr olarak kullanabilir miyiz?
Hayır. Fonksiyon, bir dizi kısıtlamayı karşılamalıdır: yeterince basit olmalı, bir return ifadesi içermeli (C++14 öncesi) veya yalnızca sabit değerlerle hesaplanabilir kod içermelidir (C++14 ve sonrası).
constexpr int f(int x) { return x + 2; } // tamam constexpr int g(int x) { int y = x + 2; return y; } // C++14 öncesi: derlenmiyor! sonrası — olur
Tüm constexpr değişkenleri derleme zamanında hesaplanabilir mi?
Hayır. Başlatma sırasında sabit olmayan bir değer kullanılırsa veya ifade derleme sırasında hesaplanamazsa hata olur.
int val; // constexpr int x = f(val); // Hata: val henüz başlatılmamış!
constexpr ile const arasındaki fark nedir?
const, yalnızca değiştirilemezliği garanti eder, ancak derleme sırasında hesaplanacağı garantisini vermez. constexpr, değerin derleme aşamasında hesaplanmasını gerektirir (mümkünse).
const int x = time(nullptr); // tamam, ancak çalışma zamanı derleniyor constexpr int y = 42; // tamam, derleme zamanında hesaplanıyor
Bir geliştirici, dairenin alanını hesaplamak için #define PI 3.14 kullanıyor.
Artıları:
Eksileri:
Bir geliştirici, constexpr double PI = 3.141592653589793; ve hesaplamalar için şablon constexpr fonksiyonları kullanıyor.
Artıları:
Eksileri: