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.
Görev
KolayKodunuzu üç dosya halinde düzenleyeceksiniz:
MathUtils.h: Derleme zamanı matematik fonksiyonlarınızı tanımlayın.Aşağıdaki fonksiyonları oluşturun:
cube— birintalan ve küpünü (n * n * n) döndüren birconstexprfonksiyontriangularNumber— n * (n + 1) / 2 formülünü kullanarak n. üçgensel sayıyı hesaplayan birconstexprfonksiyon. Bu her zaman derleme zamanında değerlendirilmelidir.sumOfSquares— iki tam sayı alan ve karelerinin toplamını (a*a + b*b) döndüren birconstexprfonksiyon
Config.h: Derleme zamanı sabitlerini kullanarak bir yapılandırma yapısı (struct) oluşturun.Üç tam sayı alan bir
constexpryapıcıya (constructor) sahip birConfigyapısı tanımlayın:width,heightvedepth. Bunları genel (public) üyeler olarak saklayın. Ayrıca width * height * depth değerini döndürenvolume()adında birconstexprmetot ekleyin.Yapının altına, 10, 20 ve 5 değerleriyle başlatılmış
DEFAULT_CONFIGadında birconstexprglobal sabit oluşturun.main.cpp: Girişten çalışma zamanı değerlerini temsil eden iki tam sayı okuyun.İlk olarak,
constexprdeğ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
constexprfonksiyonları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: 255 ve 12 girişleri için:
Cube of 4: 64
10th triangular number: 55
Default volume: 1000
Cube of 5: 125
Sum of squares: 169Kopya 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ğerlendirilirBir 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ğilDerleme 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şturulduKendin 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;
}
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
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic Konteyner12Modern C++ Özellikleri
Taşıma Semantiği ve R-değerleriMükemmel YönlendirmeDerinlemesine Lambda İfadeleristd::function ve std::bindconstexpr ve constevalYapılandırılmış Bağlamalaroptional, variant, any