2012-06-09 36 views
11

Mi sembra che manchi qualcosa di fondamentale. Sto provando ad usare i membri dell'array const al momento della compilazione.Costanti degli array in fase di compilazione

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; 
} 

Errori:

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 

Ecco la relevent IDEOne link

Allora perché non si questo lavoro? Cosa mi manca? Cosa dovrei fare in modo diverso?

risposta

9

Solo perché un oggetto è const non significa che è un'espressione costante di tempo di compilazione.

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 }; 
     ^

Questo è il motivo per constexpr:

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 

Per quanto riguarda il motivo per cui questo funziona:

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

inizializzazione di una variabile const non richiede un'espressione costante:

int foo(int n) { 
    const int a = n; // initializing const var with a non-compile time constant 
+0

Avevo pensato che il consulente sarebbe stato utile, e ora che guardo vedo che ha un'adozione più ampia di quanto pensassi. Detto questo, un po 'più di una spiegazione sul perchè la dichiarazione di const int a works ma list [1] in particolare non sarebbe apprezzata. Grazie. –

+0

OK, quindi lo studio visivo 2012 non prevede di supportare constexpr. Qualcuno ha altre soluzioni? Non DEVO usarlo per questo, ma sarebbe bello. –

+0

@ std''OrgnlDave Ho aggiunto più diagnostica del compilatore che spiega esattamente perché lista [1] non è un'espressione costante. – bames53

4

Le espressioni non sono espressioni costanti se contengono uno qualsiasi di un numero di sottoespressioni non consentite. Una tale classe di consentiti sottoespressioni è:

  • un Ivalue-to-rvalue conversione (4.1) a meno che non sia applicata a
    • un glvalue di tipo intero o di enumerazione che si riferisce ad un non -volatile oggetto const con un precedente inizializzazione, inizializzato con un'espressione costante, o
    • un glvalue di tipo letterale che si riferisce ad un oggetto non volatile definita con constexpr, o che si riferisce ad un sotto-oggetto di un tale oggetto oppure
    • un valore glaciale di tipo letterale che fa riferimento a un oggetto temporaneo non volatile la cui durata non ha terminato , inizializzata con un'espressione costante;

In particolare, mentre il nome di un oggetto const di enum o tipo integrante inizializzato con un inizializzatore costante forma un costante espressione (leggendo il suo valore è ciò che provoca il lvalue-to-rvalue conversione), gli oggetti secondari di un oggetto aggregazione const (ad esempio list nell'esempio, un array) non lo fanno, ma lo farebbero se dichiarato constexpr.

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

Questo è valido ma a non costituisce una costante espressione perché non è inizializzato con una costante espressione.

Modificando la dichiarazione di list (non è necessario modificare la dichiarazione di a), è possibile rendere a una espressione costante.

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

Come list[2] è ora una costante espressione, a ora è un oggetto const di tipo integrante inizializzato con una costante espressione così a può ora essere usato come un'espressione costante.

+0

Mi fa quasi piangere che lo studio visivo 2k12 non supporti il ​​constexpr. Non ho mai usato array come questo in metaprogrammazione di modelli, ma non vedevo l'ora di farlo ... –

Problemi correlati