`Constexpr` ve `sabit arasındaki fark`
constexpr
const
arasındaki fark nedir?
- Zaman sadece biri kullanabilir miyim?
- Ne zaman her ikisi de kullanabilir miyim ve nasıl bir seçim yapmalıyım?
CEVAP
Temel anlam ve sözdizimi
Her iki anahtar nesneler gibi işlevleri bildiriminde kullanılabilir. Uygulandığında temel farknesnelerbu:
const
bir nesne olarak bildirirsürekli. Bu başlatılan bir kez, o nesnenin değerini değiştirmeyeceğini garanti anlamına gelir, ve derleyici en iyi duruma getirmeleri için bu gerçeği. Ayrıca başlatma sonra değiştirilmesi gerekiyordu nesneleri değiştiren kod yazma programcı önlemeye yardımcı olur.constexpr
Standart dediği yerde kullanıma uygun olarak nesneyi bildirirsabit ifade. Amaconstexpr
bunu yapmak için tek yol olduğunu unutmayın.
Uygulandığındafonksiyonlartemel fark şu:
const
sadece statik olmayan üye işlev, genel olarak işlevleri için kullanılabilir. Üye işlevi statik olmayan veri üyeleri herhangi bir değişiklik olmayan bir garanti verir.constexpr
üye ve üye olmayan fonksiyonları ile, kurucular kullanılabilir. Bu fonksiyonu kullanmak için uygun olmadığını ilan ediyorsabit ifade. Derleyici yalnızca işlevi belirli kriterleri (7.1.5/3,4), en önemlisi uyuyorsa onu kabul eder(†):- Fonksiyonun sanal olmayan ve son derece basit olmalı: typedefs ve statik iddia Dışında
return
yalnızca tek bir deyim izin verilir. Bir kurucu, sadece bir başlatma listesi, typedefs ve statik durumda iddia izin verilir. (= default
= delete
de izin verilir.) - Bağımsız değişkenleri ve dönüş türü olmalıedebi tür(yani, genel olarak konuşursak, çok basit türler, genellikle skaler veya toplamları)
- Fonksiyonun sanal olmayan ve son derece basit olmalı: typedefs ve statik iddia Dışında
Sabit ifade
Olarak, constexpr
iki nesne gibi işlevleri bildirir sabit ifadeler kullanmak için uygun olarak yukarıda söyledi. Sabit bir ifade birden fazla yalnızca sabittir:
Derleme zamanı değerlendirme, örneğin, ve dizi boyutu şablon parametreleri belirteçleri: gerektiren yerlerde kullanılabilir
template <int N> class fixed_size_list { /*...*/ }; fixed_size_list<X> mylist; // <-- X must be an integer constant expression int numbers[X]; // <-- X must be an integer constant expression
Aman dikkat
constexpr
olarak ilan eden bir şeyler mutlaka derleme zamanında değerlendirilecektir garanti etmez.kullanılabilirbu, ancak çalışma zamanı, aynı zamanda değerlendirilen diğer yerlerde kullanılabilir.Bir nesneolabilirsabit ifadeler kullanmak için uygun olabilirolmadanbildirilmiş
constexpr
. Örnek:int main() { const int N = 3; int numbers[N] = { 1 , 2, 3 }; // <-- N is constant expression /*...*/ }
Bu
N
ve bir edebi ile beyan zamanda sürekli başlatılmış, eğerconstexpr
ilan değil ise bile sabit bir ifade kriterlerini karşılar, çünkü bu mümkündür.
Aslında constexpr
kullanmak zorunda mıyım?
Birnesne
N
gibi yukarıda sabit ifadesi olarak kullanılabilirolmadanbildirilmişconstexpr
. Bu tüm nesneler için de geçerlidir:const
- integral ya da numaralandırma türüve
- kendisi sabit bir ifade bir ifade ile beyan zamanda başlatıldı
[Bunun nedeni §5.19/2: sabit ifade etmemeli vardır bir taşıyıcının bu içerir "bir lvalue-rvalue değişiklik olmadığı sürece [...] bir glvalue ayrılmaz ya da numaralandırma türü [...]". Teşekkürler bu edebi tür gerçek olduğunu daha önceki iddiamı düzeltmek için Richard Smith] Bir içinişlevisabit ifadeler kullanmak için uygun olması içingerekiraçıkça
constexpr
, sadece ifade sabit fonksiyonlar için kriterleri karşılamak için yeterli olduğunu ilan etti. Örnek:template <int N> class list { }; constexpr int sqr1(int arg) { return arg*arg; } int sqr2(int arg) { return arg*arg; } int main() { const int X = 2; list<sqr1(X)> mylist1; // OK; sqr1 is constexpr list<sqr2(X)> mylist2; // Wrong; sqr2 is not constexpr return 0; }
Zaman / I, const
constexpr
hem kullanmalıdırbirlikte?
a) bildirimleri nesneBu iki anahtar kelimeler ilan edilmesi de aynı nesneyi gösterecektir zaman zaman gerekli değildir. constexpr
const
anlamına gelir.
constexpr const int N = 5;
aynı gibi
constexpr int N = 5;
Ancak, anahtar kelimeler her bildirim farklı bölgelerine bakın durumlar olabilir:
static constexpr int N = 3;
int main()
{
constexpr const int *NP = &N;
return 0;
}
Burada, NP
Adres sabiti ifadesi olarak bildirilmiş, yani bir işaretçi, kendisi sürekli bir ifadesidir. (Bu adresi statik/sabit genel bir ifade için adres operatörünü uygulayarak oluşturulduğunda mümkündür.) Burada, her iki constexpr
const
gereken: constexpr
her zaman ifade eder ifade bildirilmiş (burada NP
), const
gösterir int
(bildirir bir işaretçi-sabit). Çıkarma const
ki render ifade yasadışı (çünkü (a) bir işaretçi olmayan sabit nesne olamaz sabit ifade ve (b) &N
-aslında bir işaretçi-sürekli).
b) üye işlevi bildirimleriC 11, constexpr
const
ayrıca üye fonksiyonları anlamına gelir. Ancak, bu C 14 değişmiş olabilir. Mevcut taslaklar, constexpr
göre ima edecek const
nesneler sadeceüye fonksiyonları , 7.1.5/8 madde için önerilen değişiklik nedeniyle değil. Dolayısıyla, bir üye işlev C 11 olarak ilan edildi
constexpr void f();
olarak ilan edilecek
constexpr void f() const;
sırada C 14 altında hala const
bir fonksiyonu olarak kullanılabilir.Bir sürü kod daha sonra değiştirmek zorunda kalmamak için en iyi const
constexpr
üye fonksiyonlar bile artık mark.
(†)constexpr
kabul edilebilir fonksiyonlar için koşullar muhtemelen C 14 için rahat olacak. proposal by Richard Smith son adopted into the C 14 draft olmuştur.
Sembolik bağlantı ve sabit bir bağlant...
Ne'In arasındaki fark "Norma...
Template Metaprogramming - Numaralama ...
Sabit*, int * sabit ve sabit int *int ...
* Sabit ve sabit char *char arasındaki...