Menu
Coddy logo textTech

constexpr ve consteval

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 87 / 104.

C++, hesaplamaların çalışma zamanı yerine derleme zamanında gerçekleşmesine olanak tanır; bu da performansı önemli ölçüde artırabilir. constexpr anahtar kelimesi (C++11) ve consteval anahtar kelimesi (C++20), ifadelerin ne zaman değerlendirileceği üzerinde kontrol sahibi olmanızı sağlar.

Bir constexpr fonksiyonu, sabit argümanlar verildiğinde derleme zamanında değerlendirilebilir ancak sabit olmayan girdilerle çalışma zamanında da çalışabilir:

#include <iostream>

constexpr int square(int n) {
    return n * n;
}

int main() {
    constexpr int compileTime = square(5);  // Derleme zamanında hesaplanır
    
    int x = 7;
    int runtime = square(x);  // Çalışma zamanında hesaplanır
    
    std::cout << compileTime << "\n";  // 25
    std::cout << runtime << "\n";      // 49
}

Derleme zamanı değerlendirmesini garanti etmeniz gerektiğinde consteval kullanın. Bir consteval fonksiyonu bir sabit üretmelidir; onu çalışma zamanı değerleriyle çağırmak bir derleme hatasıdır:

consteval int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

int main() {
    constexpr int result = factorial(5);  // TAMAM: 120 derleme zamanında hesaplandı
    
    // int x = 5;
    // int bad = factorial(x);  // HATA: x bir sabit değil
}

Ayrıca constexpr ifadesini değişkenlerle ve hatta sınıf yapıcılarıyla birlikte kullanarak tüm nesnelerin derleme zamanında oluşturulmasını sağlayabilirsiniz. Bu, özellikle arama tabloları, yapılandırma değerleri veya programın yürütülmesi sırasında değişmeyen tüm veriler için oldukça kullanışlıdır.

challenge icon

Görev

Kolay

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • MathUtils.h: Derleme zamanı matematik fonksiyonlarınızı tanımlayın.

    Aşağıdaki fonksiyonları oluşturun:

    • cube — bir int alan ve küpünü (n * n * n) döndüren bir constexpr fonksiyon
    • triangularNumber — n * (n + 1) / 2 formülünü kullanarak n. üçgensel sayıyı hesaplayan bir constexpr fonksiyon. Bu her zaman derleme zamanında değerlendirilmelidir.
    • sumOfSquares — iki tam sayı alan ve karelerinin toplamını (a*a + b*b) döndüren bir constexpr fonksiyon
  • Config.h: Derleme zamanı sabitlerini kullanarak bir yapılandırma yapısı (struct) oluşturun.

    Üç tam sayı alan bir constexpr yapıcıya (constructor) sahip bir Config yapısı tanımlayın: width, height ve depth. Bunları genel (public) üyeler olarak saklayın. Ayrıca width * height * depth değerini döndüren volume() adında bir constexpr metot ekleyin.

    Yapının altına, 10, 20 ve 5 değerleriyle başlatılmış DEFAULT_CONFIG adında bir constexpr global sabit oluşturun.

  • main.cpp: Girişten çalışma zamanı değerlerini temsil eden iki tam sayı okuyun.

    İlk olarak, constexpr değişkenler oluşturarak derleme zamanı değerlendirmesini gösterin:

    • cube(4) değerini bir constexpr değişkende saklayın ve yazdırın: Cube of 4: [value]
    • triangularNumber(10) değerini bir constexpr değişkende saklayın ve yazdırın: 10th triangular number: [value]
    • Varsayılan yapılandırmanın hacmini yazdırın: Default volume: [value]

    Ardından, iki giriş değerinizi kullanarak constexpr fonksiyonların çalışma zamanında da çalışabildiğini gösterin:

    • İlk girişle cube() fonksiyonunu çağırın ve yazdırın: Cube of [input]: [result]
    • Her iki girişle sumOfSquares() fonksiyonunu çağırın ve yazdırın: Sum of squares: [result]

Örneğin, 3 ve 4 girişleri için:

Cube of 4: 64
10th triangular number: 55
Default volume: 1000
Cube of 3: 27
Sum of squares: 25

5 ve 12 girişleri için:

Cube of 4: 64
10th triangular number: 55
Default volume: 1000
Cube of 5: 125
Sum of squares: 169

Kopya kağıdı

C++ , constexpr (C++11) ve consteval (C++20) anahtar kelimelerini kullanarak derleme zamanında (compile time) hesaplamalar yapılmasına olanak tanır.

Bir constexpr fonksiyonu, sabit argümanlarla derleme zamanında değerlendirilebilir ancak sabit olmayan girdilerle çalışma zamanında (runtime) da çalışır:

constexpr int square(int n) {
    return n * n;
}

constexpr int compileTime = square(5);  // Derleme zamanında değerlendirilir

int x = 7;
int runtime = square(x);  // Çalışma zamanında değerlendirilir

Bir consteval fonksiyonu derleme zamanında değerlendirilmek zorundadır. Bu fonksiyonu çalışma zamanı değerleriyle çağırmak bir derleme hatasına neden olur:

consteval int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

constexpr int result = factorial(5);  // Tamam: derleme zamanında hesaplandı

// int x = 5;
// int bad = factorial(x);  // HATA: x bir sabit değil

Derleme zamanında nesne oluşturmayı etkinleştirmek için değişkenler, sınıf kurucuları ve metotlarla constexpr kullanabilirsiniz:

struct Config {
    int width, height, depth;
    
    constexpr Config(int w, int h, int d) 
        : width(w), height(h), depth(d) {}
    
    constexpr int volume() const {
        return width * height * depth;
    }
};

constexpr Config config(10, 20, 5);  // Derleme zamanında oluşturuldu

Kendin dene

#include <iostream>
#include "MathUtils.h"
#include "Config.h"

using namespace std;

int main() {
    // Girdiden iki tam sayı oku
    int input1, input2;
    cin >> input1;
    cin >> input2;
    
    // TODO: Derleme zamanı (compile-time) değerlendirmesini göster
    // cube(4) değerini saklayan bir constexpr değişkeni oluştur ve yazdır: "Cube of 4: [value]"
    
    // TODO: triangularNumber(10) değerini saklayan bir constexpr değişkeni oluştur
    // ve yazdır: "10th triangular number: [value]"
    
    // TODO: Varsayılan yapılandırmanın (config) ses seviyesini yazdır: "Default volume: [value]"
    
    // TODO: constexpr fonksiyonların çalışma zamanı (runtime) kullanımını göster
    // input1 ile cube() fonksiyonunu çağır ve yazdır: "Cube of [input1]: [result]"
    
    // TODO: Her iki girdi ile sumOfSquares() fonksiyonunu çağır
    // ve yazdır: "Sum of squares: [result]"
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler