2016-05-24 19 views
7

Il seguente codice ha un disperato bisogno : values() compilare, almeno in Ideone :: C++ 14:Perché è necessario inizializzare un membro di array non statico in una classe constexpr?

#include <iostream> 

template<int N> 
struct Table 
{ 
    constexpr Table() : values() 
    { 
     for (auto i = 0; i < N; ++i) 
     { 
      values[i] = i * i * i; 
     } 
    } 
    int values[N]; 
}; 

int main() { 
    constexpr auto a = Table<1000>(); 
    for (auto x : a.values) 
     std::cout << x << '\n'; 
} 

Ma perché? Avevo pensieri lungo "i valori potrebbero anche essere inizializzati in modo non consecutivo e valori() dicono esplicitamente che inizializziamo in modo conforme a constexpr". Ma non sta omettendo lo : values() altrettanto chiaro?

+0

'clang' dà uno strano messaggio:' assegnazione a oggetto al di fuori della sua durata non è consentita in un'espressione costante' per '=' nel costruttore di 'Table' se ometto' values ​​() '. – Holt

+0

"per il costruttore di una classe o di una struttura, ogni oggetto secondario di classe di base e ogni membro di dati non statici non varianti deve essere inizializzato." – krOoze

+0

Tuttavia, è inizializzato in ogni caso, solo Non esplicito in ogni caso. Funziona per le classi non-constexpr – IceFire

risposta

5

Considerare la semantica.

L'omissione del membro dall'elenco di inizializzazione eseguirà l'inizializzazione predefinita, che in questo caso lascia l'array con valori non specificati. Ciò annulla lo scopo di un constexpr.

Il valore di inizializzazione dell'array esegue l'inizializzazione zero su ciascun elemento di matrice (poiché si tratta di una matrice di tipi incorporati).

+0

questo ha davvero senso e non sapevo che – IceFire

+0

Ancora, perché non è consentito inizializzare gli elementi nel ciclo for? Successivamente, tutti gli elementi dell'array hanno valori –

+0

@ JohannesSchaub-litb, per semplicità di implementazione, penso. A giudicare dalla citazione che Serge ha mormorato, il comitato potrebbe aver pensato che la catena c'tor potrebbe essere meno intrattabile del rintracciare un corpo arbitrario. – StoryTeller

2

Semplicemente perché è richiesto dallo standard. Progetto di n4296 per i C++ stati standard a:

7.1.5 L'identificatore constexpr [dcl.constexpr] § 4 (sottolineare il mio):

4 La definizione di un costruttore constexpr devono soddisfare i seguenti vincoli:
...

Inoltre, sia la sua funzione-corpo sarà = cancella, o che essa deve soddisfare i seguenti vincoli:

(4.4) - sia la sua funzione-corpo sarà = default, oppure il dichiarazione composta della sua f il corpo unction deve soddisfare i vincoli per un corpo funzione di una funzione constexpr;
(4.5) - ogni membro dati non statico non statico e oggetto secondario classe base deve essere inizializzato (12.6.2);
...

+1

Forse lo standard dovrebbe chiarire in realtà che l'inizializzazione predefinita non si applica come "inizializzata". Tuttavia, avere un valore non specificato dovrebbe precludere di essere un "constexpr", quindi credo che ne consegue logicamente. – StoryTeller

Problemi correlati