2012-10-11 9 views
5

Assumere:È possibile costruire gli elementi di un array membro in base a un parametro di modello integrale?

template<class T,int N> 
struct A { 
    A(): /* here */ {} 

    T F[N]; 
}; 

ho bisogno di elementi di F[] da costruire con {0,1,2,...,N-1}. Se possibile, vorrei evitare le strutture template definite ricorsivamente definendo l'ultimo livello come template<class T> struct A<T,0> e facendo alcuni complicati trucchi sui template. Gli elenchi di inizializzatori C++ 11 possono essere d'aiuto?

Questo è simile a Template array initialization with a list of values, ma non costruisce gli elementi con il valore crescente. Lo imposta successivamente in un ciclo di runtime.

+0

perché non può gamma essere utilizzato qui? – Jagannath

+0

Può, ma non risolve questo problema – ritter

risposta

2

Assumendo un qualche tipo di soluzione è disponibile indices:

A(): A(make_indices<N>()) {} 

// really a private constructor 
template<int... Indices> 
explicit A(indices<Indices...>) 
    // Can be an arbitrary expression or computation, too, like 
    // (Indices + 3)... 
    : F {{ Indices... }} 
{} 

Se il compilatore non supporta costruttori delega, una possibilità è quella di passare a std::array<T, N> e utilizzare un aiutante statica privata che restituisce un array inizializzato, ad esempio che il costruttore predefinito diventerebbe:

A(): F(helper(make_indices<N>())) {} 

Ciò comporterebbe naturalmente una costruzione aggiuntiva (spostamento).

+0

[Completa demo su LWS] (http://liveworkspace.org/code/9894e8cb01d5f7af1bbbef5e04397a16). –

+0

Questo è molto bello! – ritter

+0

Questo 'uso' è del tutto necessario. Il mio compilatore GCC 4.6 non lo capisce – ritter

4

È possibile farlo con un modello di valore e costruttore delegazione variadic:

template<int... I> struct index { 
    template<int n> using append = index<I..., n>; }; 
template<int N> struct make_index { typedef typename 
    make_index<N - 1>::type::template append<N - 1> type; }; 
template<> struct make_index<0> { typedef index<> type; }; 
template<int N> using indexer = typename make_index<N>::type; 

template<class T, int N> 
struct A { 
    template<T...I> A(index<I...>): F{I...} {} 

    A(): A(indexer<N>{}) {} 

    T F[N]; 
}; 

Questo utilizza il generatore di pacchetto sequenza dal Calling a function for each variadic template argument and an array

+0

L'uso di 'using' è essenziale per la soluzione? – ritter

+0

@Frank no, può sempre essere sostituito da 'typedef'. È solo conveniente in questo caso. – ecatmur

+0

Ho votato - mi piace come i modelli possono essere completamente illeggibili nel nuovo standard ;-) –

Problemi correlati