SORU
2 Ocak 2013, ÇARŞAMBA


`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
2 Ocak 2013, ÇARŞAMBA


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. Ama constexpr 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ı)

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ğer constexpr 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?

  • BirnesneN 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 constnesneler 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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Chip Johnson

    Chip Johnson

    30 AĞUSTOS 2007
  • Palmundo Ec

    Palmundo Ec

    11 HAZİRAN 2009
  • xdadevelopers

    xdadeveloper

    25 Aralık 2009