2012-10-11 26 views
5

Supongamos:¿Es posible construir los elementos de una matriz miembro en función de un parámetro de plantilla integral?

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

    T F[N]; 
}; 

necesito los elementos de F[] a ser construido con {0,1,2,...,N-1}. Si es posible me gustaría evitar estructuras de plantillas definidas recursivamente de definir el último nivel que template<class T> struct A<T,0> y hacer de las suyas plantilla complicados. ¿Pueden ayudar las listas de inicializadores de C++ 11?

Esto es similar Template array initialization with a list of values, pero no construye los elementos con el valor creciente. Lo establece más tarde en un ciclo de tiempo de ejecución.

+0

por qué no puede ser utilizado gama aquí? – Jagannath

+0

Se puede, pero no resuelve este problema – ritter

Respuesta

2

Suponiendo algún tipo de solución está disponible 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... }} 
{} 

Si el compilador no admite delegación de constructores, una opción es cambiar a std::array<T, N> y utilizar un ayudante estática privada que devuelve una matriz inicializada, tales que el constructor predeterminado sería:

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

Esto, por supuesto, incurriría en una construcción adicional (movimiento).

+0

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

+0

¡Esto es genial! – ritter

+0

¿Es esto 'usar' completamente necesario. Mi compilador GCC 4.6 no lo entiende – ritter

4

Usted puede hacer esto con una plantilla de valor y el constructor de delegación 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]; 
}; 

Esto utiliza el generador de paquete de secuencia de Calling a function for each variadic template argument and an array

+0

¿El uso de 'using' es esencial para la solución? – ritter

+0

@Frank no, siempre se puede reemplazar por 'typedef'. Es conveniente en este caso. – ecatmur

+0

He votado - Me encanta cómo las plantillas pueden ser completamente ilegibles en el nuevo estándar ;-) –

Cuestiones relacionadas