2014-07-25 18 views
5

sto cercando di inizializzare oggetti di tipo cosa:Come inizializzare un oggetto di std :: array <std :: array <T, 2>, 2>?

template<typename T> 
    struct thing : std::array<std::array<T, 2>, 2> 
    { 
    }; 

thing<int> t1 {{ {1,2}, {3,4} }}; 

ottengo:

error: no matching function for call to ‘thing<int>::thing(<brace-enclosed initializer list>)’ 
thing<int> t1 {{{1,2},{3,4}}}; 

Idem con

thing<int> t0{{ 1, 2, 3, 4 }}; 

e diverse altre cose.

+3

perché stai legando per ereditare da un array 2D? – rashmatash

+2

Se si sta tentando di creare un alias dell'array, è meglio fare 'template usando thing = std :: array , 2>;' – Quentin

risposta

9

Se si utilizza un compilatore C++ 17, mancherà solo un set aggiuntivo di parentesi graffe. Il seguente compiles:

thing<int> t1 { { { {1,2}, {3,4} } } }; 
//   | | | |- braces for inner array 
//   | | |--- braces for outer array 
//   | |----- braces for base sub object of thing 
//   |------- braces for list initialization of thing 

C++ 17 modified le regole per aggregati per consentire classi di base, purché siano public e non virtual.

Da §11.6.1/1 [dcl.init.aggr]

Un aggregato è un array o una classe con
(1.1) senza costruttori forniti dall'utente, explicit, o ereditato ([class.ctor]),
(1.2) nessun membro di dati non statici privato o protetto ([class.access]),
(1.3) senza funzioni virtuali e
(1.4) nessuna classe di base virtuale, privata o protetta ([class.mi]).

Le classi base sono ora considerati elements of the aggregate, e possono a loro volta essere inizializzate con lista-inizializzazione.

Gli elementi di un aggregato sono:
(2.1) per un array, gli elementi della matrice in ordine crescente pedice o
(2.2) per una classe, le classi base dirette in dichiarazione ordine, seguito dai membri diretti non statici dei dati ([class.mem]) che non sono membri di un'unione anonima, in ordine di dichiarazione.


C++ 14, e precedenti, la versione della risposta segue:

std::array è un aggregato, e l'inizializzazione fatto utilizzando un-init-list rinforzato è aggregata inizializzazione. Tuttavia, thing non è un aggregato perché ha una classe base.

Da §8.5.1/1 [dcl.init.aggr]

Un aggregato è un array o una classe (Clausola 9) senza costruttori forniti dall'utente (12.1), senza componenti di dati privati ​​o protetti non statico (par 11), nessuna base classi (articolo 10) e nessuna funzione virtuale (10.3).

Pertanto, l'inizializzazione di aggregazione non funzionerà. A seconda di cosa si sta cercando di fare, sia desidera fornire un costruttore per thing che prende un argomento std::array<std::array<T, 2>, 2>, e inizializzare il sotto-oggetto base di

template<typename T> 
struct thing : std::array<std::array<T, 2>, 2> 
{ 
    thing(std::array<std::array<T, 2>, 2> arr) 
    : std::array<std::array<T, 2>, 2>(arr) 
    {} 
}; 
thing<int> t{ {{ {{1,2}}, {{3,4}} }} }; 

O avere thing contengono la std::array come un membro di dati. Ora thing è ancora un aggregato.

template<typename T> 
struct thing 
{ 
    std::array<std::array<T, 2>, 2> arr; 
}; 
thing<int> t{ {{ {{1,2}}, {{3,4}} }} }; 

Se state cercando di fare è di avere thing essere un alias per un array<array<T,2>,2>, allora non hai bisogno né di quanto sopra. Usa

template<typename T> 
using thing = std::array<std::array<T, 2>, 2>; 

thing<int> t{{ {{1,2}}, {{3,4}} }}; 
Problemi correlati