2016-12-05 19 views
28

C++ 1z "constexpr if" ifadesini tanıtacaktır - eğer koşullara bağlı olarak dallardan biri çıkarılacaksa. Makul ve kullanışlı görünüyor."constexpr" vs "ise" en iyi duruma getirme - neden "constexpr" gerekli?

Ancak, constexpr anahtar sözcüğü olmadan yapmak mümkün değil mi? Derleme sırasında derleyicinin, derleme zamanı sırasında wheter koşulunun bilindiğini bilmesi gerektiğini düşünüyorum. Öyleyse, en temel optimizasyon seviyesi bile gereksiz şube kaldırmalıdır. O0 bile gcc-4.4.7 derlemek "return 1" olmadığını,

int test() { 
    const bool condition = true; 
    if (condition) { 
     return 0; 
    } else { 
     // optimized out even without "constexpr if" 
     return 1; 
    } 
} 

Godbolt kaşif gösterileri, bu yüzden birlikte ne vaat edildi Hedefler:

Örneğin (: https://godbolt.org/g/IpY5y5 Godbolt görmek) eğer varsa. Açıkçası böyle bir eski derleyici durumun constexpr işlevinin sonucu olduğu zaman bunu yapamayacaktır, ancak gerçek şu ki: modern derleyici durumun constexpr olup olmadığını bilir ve açık bir şekilde söylememe gerek duymaz.

Yani soru şu:

Neden "constexpr" "eğer constexpr" ihtiyaç vardır?

+7

Bu sadece bir optimizasyon meselesi değildir: “constexpr” in geçersiz olduğu bir alanın geçersiz olmasına izin verilir, yani kendi başına derlenmez. Senin sorunun duruyor. – Quentin

cevap

38

Bu bir örnekle açıklamak kolaydır.

struct Cat { void meow() { } }; 
struct Dog { void bark() { } }; 

ve if ifadesinin her iki dalları var çünkü, bir derleme hatası (wandbox example) tetikleyecek

pet(Cat{}); 
pet(Dog{}); 

çağırma

template <typename T> 
void pet(T x) 
{ 
    if(std::is_same<T, Cat>{}){ x.meow(); } 
    else if(std::is_same<T, Dog>{}){ x.bark(); } 
} 

şekilde biçimlendirilmiş olması için düşünün. koşul (wandbox example) şekilde biçimlendirilmiş olması gerekiyor maçları sadece dalı - if constexpr

template <typename T> 
void pet(T x) 
{ 
    if constexpr(std::is_same<T, Cat>{}){ x.meow(); } 
    else if constexpr(std::is_same<T, Dog>{}){ x.bark(); } 
} 

kullanmak pet değiştirme

prog.cc:10:40: error: no member named 'bark' in 'Cat' 
    else if(std::is_same<T, Dog>{}){ x.bark(); } 
            ~^
prog.cc:15:5: note: in instantiation of function template specialization 'pet<Cat>' requested here 
    pet(Cat{}); 
    ^
prog.cc:9:35: error: no member named 'meow' in 'Dog' 
    if(std::is_same<T, Cat>{}){ x.meow(); } 
           ~^
prog.cc:16:5: note: in instantiation of function template specialization 'pet<Dog>' requested here 
    pet(Dog{}); 
    ^

sadece dalları ayrıştırılabilir olmasını gerektirir.

beklendiği gibi

pet(Cat{}); 
pet(Dog{}); 

derlemek ve çalışma olacaktır pasajı.

+1

Teşekkür ederiz. "Parseable" ve "iyi biçimlenmiş" arasındaki ayrım, önce :-) 'yi aldattı – MateuszL

İlgili konular