2012-06-09 39 views
11

Temel olmayan bir şeyi kaçırıyor gibi görünüyor. Derleme zamanında const dizisi üyelerini kullanmaya çalışıyorum.Derleme zamanı dizi sabitleri

const int list[3] = { 2, 5, 7 }; 
const int a = list[2]; // this doesn't error? 

template<int N1, int N2> 
struct tmax { 
    enum { value = ((N1 > N2) ? N1 : N2) }; 
}; 

const int b = tmax<2,4>::value; 
const int c = tmax<list[0],list[1]>::value; // error is here 

int main() 
{ 
    return 0; 
} 

hatalar: Burada

prog.cpp:10:24: error: 'list' cannot appear in a constant-expression 
prog.cpp:10:30: error: an array reference cannot appear in a constant-expression 

Peki neden bu işi yapar relevent IDEOne link

mı? Neyi kaçırıyorum? Ne farklı yapmalıyım?

cevap

9

Bir nesnenin const olması, bunun bir derleme zaman sabiti ifadesi olduğu anlamına gelmez.

int foo(int n) { 
    const int a = n; // initializing const var with a non-compile time constant 
: sabit ifadesini gerektirmeyen bir const değişkeni başlatılıyor

const int a = list[2]; // this doesn't error? 

: neden bu çalışır gelince

constexpr int list[3] = { 2, 5, 7 }; 

template<int N1, int N2> 
struct tmax { 
    enum { value = ((N1 > N2) ? N1 : N2) }; 
}; 

const int b = tmax<2,4>::value; 
const int c = tmax<list[0],list[1]>::value; // works fine now 

:

main.cpp:10:20: error: non-type template argument is not a constant expression 
const int c = tmax<list[0],list[1]>::value; // error is here 
        ^~~~~~~ 
main.cpp:10:20: note: read of non-constexpr variable 'list' is not allowed in a constant expression 
main.cpp:1:11: note: declared here 
const int list[3] = { 2, 5, 7 }; 
     ^

Bu

constexpr nedeni
+0

Constexpr'in yardımcı olacağını düşündüm ve şimdi görüyorum ki düşündüğümden daha geniş bir evlatlık var. Bununla birlikte, özellikle const [1] listesindeki bir yapının bildirilmesinin neden özel olarak anlaşılmayacağı ile ilgili bir açıklama. Teşekkür ederim. –

+0

Tamam, bu yüzden görsel stüdyo 2012, constexpr'ı desteklemeyi planlamıyor. Başka bir çözümü olan var mı? Bunu bunun için kullanmam gerekmiyor, ama güzel olurdu. –

+0

@ std''OrgnlDave Tam olarak neden listenin [1] sabit bir ifade olmadığını açıklayan daha fazla derleyici tanılama ekledim. – bames53

4

İfadeler, izin verilmeyen birkaç alt ifadeden herhangi birini içeriyorsa sabit ifadeleri değildir. izin alt ifadeler bir sınıfı olan:

  • bir lvalue-için-rvalue bu
    • olmayan bir değinmektedir yekpare veya sıralama tipi bir glvalue uygulanır sürece dönüşüm (4.1) sabit bir ifade ile başlatılan bir önceki başlatma ile const nesne -volatile veya
    • constexpr ile tanımlanan bir uçucu olmayan nesneye atıfta değişmez tipte bir glvalue, ya da böyle bir nesnenin bir alt nesneye değinmektedir veya
    • , ömür boyu sona erdirilmiş, sabit bir ifadeyle başlatılan geçici olmayan geçici bir nesneyi ifade eden bir tamsayı türü; enum veya sabit bir başlatıcı ile başlatılır intergral tipte bir const nesne adı sabit ifade (okuma değerini oluşturur Özel olarak

, lvalue-için-rvalue neden olur()), bir const aggregate nesnesinin alt nesnesi (örneğinizdeki list gibi bir dizi) bunu yapmaz, ancak constexpr bildirmişse.

const int list[3] = { 2, 5, 7 }; 
const int a = list[2]; 

Bu geçerli ama bir sabit ifadesi ile başlatılmadı nedeniyle bir sabit ifadesinia teşkil etmez.

list bildirimini değiştirerek (a bildirimini değiştirmek zorunda değiliz), a sabit bir ifade oluşturabiliriz. list[2] olarak

constexpr int list[3] = { 2, 5, 7 }; 
const int a = list[2]; 

a şimdi a hemen sabit bir ifade olarak kullanılabilecek bir sabit ifade ile başlatılır intergral tip bir const amacı, hemen bir sabit ifadesi olup.

+0

Neredeyse beni 2k12 görsel stüdyosunun constexpr desteklemeyeceğini ağlatıyor. Şablon meta programlamasında böyle diziler kullanmamıştım ama bunu dört gözle bekliyordum ... –

İlgili konular