2010-01-29 16 views
8

¿Hay alguna forma de restringir el tamaño de una matriz cuando se pasa como argumento a una función?Restricción del tamaño de una matriz cuando se pasa a una función

Quiero decir es algo como posible?

/*following will lead to compile time error */ 

template<typename T, size_t n>=20> // or template<typename T,size_t n<=20> 
void func(T (&a)[n]) 
{ 
    // do something with a 

} 

Quiero que el tamaño de mi matriz a ser por lo menos (oa lo sumo) n (n puede tener cualquier valor).

Por ejemplo:

Cuando n=20 I debe pasar una matriz con por lo menos (o en más) 20 elementos. ¿Hay alguna forma en C++ para esto?

+1

¿Qué comportamiento desea si la matriz no es del tamaño correcto? –

+1

@Neil: Error de compilación. –

Respuesta

15

Simplemente puede hacer que el requisito sea una aserción estática, p. con Aumenta afirman estática:

template<typename T, size_t n> 
void func(T (&a)[n]) { 
    BOOST_STATIC_ASSERT(n >= 20); 
    // ... 
} 

una implementación personalizada básica (no resolver el problema de usarlo más de una vez por alcance) podría tener el siguiente aspecto:

template<bool b> struct StaticAssert; 
template<> struct StaticAssert<true> {}; 
#define STATIC_ASSERT(x) StaticAssert<(x)> static_asserter 

Si desea un comportamiento diferente si se cumple el requisito, use algo como enable_if o especialización basada en etiquetas. Ejemplo usando enable_if:

template<class T, size_t n> 
typename boost::enable_if<(n >= 20), void>::type 
func(T (&a)[n]) { /* ... */ } 

template<class T, size_t n> 
typename boost::disable_if<(n >= 20), void>::type 
func(T (&a)[n]) { /* ... */ } 
+2

Nota: Conocer el tamaño no le impide acceder más allá del final (es decir, el compilador no verificará los índices de su matriz). –

+0

+ 1 muy intersting: no sabía acerca de esta macro, que permite recibir un error de tiempo de compilación. – sergiom

+0

el mecanismo de plantilla de C++ patea el culo! si le parece interesante, obtenga los libros de mi respuesta. : D –

-2

Está intentando utilizar plantillas (tiempo de compilación) para saber cuántos elementos estarán en la matriz en tiempo de ejecución. No es posible hacer lo que intentas hacer.

Usted tendrá que depender de código fuera de su función o dentro de la función

+2

por supuesto, el mecanismo de la plantilla en C++ se está completando. –

+0

Las matrices en sentido estricto tienen su tamaño fijado en tiempo de compilación. – visitor

-3

No hay una construcción de este tipo en C++, que le permite recibir un error de tiempo de compilación. Pero creo que al usar plantillas podría implementar un marco que contenga algo así como una clase LimitedArray para usar en lugar de un tipo de matriz básica.

5

La respuesta de GF es correcta, si desea obtener más características o puntos de decisión en tiempo de compilación, es posible que desee consultar boost::mpl. C++ Template Metaprogramming describe qué es posible con boost :: MPL y cómo fue diseñado. Modern C++ design, que no está relacionado con MPL, entra en técnicas de diseño que aprovechan el polimorfismo de tiempo de compilación

+0

Pensé que uno no debería tener que seguir los enlaces para ver a qué libros se refiere, simplemente cámbielo si no le conviene. –

+0

gracias gf, estaba siendo flojo: P –

3

La respuesta de GF es genial, pero Boost.Array no puede pasar desapercibido.

template< typename T > 
void func(boost::array< T, 20 > &a) { 

Dada su pregunta y la respuesta de GF, se ve como una conversión implícita computacionalmente libre, tipo y gama-salvo de T(&)[20] a some_array_template<T,20> sería semánticamente posible, pero boost::array no permite eso. Aún así, podría considerar pasar por completo al boost::array si tiene mucha lógica similar. Y es lo suficientemente simple como para usarla como base para desarrollar la tuya, si quieres una conversión implícita.

Cuestiones relacionadas