the number length largo know array c++ arrays templates size sizeof

c++ - number - ¿Cómo funciona esta plantilla de "tamaño de matriz"?



size of array c++ (1)

Posibles duplicados:
¿Alguien puede explicar este código de plantilla que me da el tamaño de una matriz?
Argumentos mágicos en plantillas de funciones ...

¿Alguien puede explicar cómo funciona este código? Sé que el objetivo de este código es obtener la longitud de una matriz, pero no sé cómo funciona este código:

template<typename T, int size> int GetArrLength(T(&)[size]){return size;}

Gracias.


Primero analicemos el parámetro, T(&)[size] . Lea las declaraciones de adentro hacia afuera, de derecha a izquierda, primero el grupo de paréntesis: es un parámetro sin nombre que hace referencia a una matriz de tamaño de size de tipo T

Es decir, acepta una referencia a cualquier matriz, donde el tipo y el tamaño de la matriz son parámetros de plantilla.

Si lo llamamos así:

int a[10]; GetArrLength(a);

El compilador intentará deducir los parámetros de la plantilla. Para que el tipo de parámetro coincida con lo que está pasando, T debe ser int y el size debe ser 10 (lo que hace que el parámetro sea una referencia a una matriz de 10 int s).

A continuación, devuelve ese tamaño, que le da la cantidad de elementos en una matriz.

Hay dos "problemas" con este código. En primer lugar, los tamaños no pueden ser negativos, por lo que no tiene sentido utilizar un tipo con signo como parámetro de plantilla y tipo de retorno. Por el contrario, se debe utilizar un tipo sin signo; lo mejor sería std::size_t :

template<typename T, std::size_t Size> std::size_t GetArrLength(T(&)[Size]) { return size; }

El segundo es que el resultado de esta función no es una expresión constante, a pesar de que el tamaño de una matriz sí lo es. Si bien eso está bien en la mayoría de las situaciones, sería mejor si pudiéramos obtener una expresión constante de ello. Ahí es donde terminas con esta solución:

template <std::size_t N> struct type_of_size { typedef char type[N]; }; template <typename T, std::size_t Size> typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]); #define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray))

Esto se usa como tal:

int a[10]; const std::size_t n = sizeof_array(a); // constant-expression!

Funciona de tres maneras: la primera es la misma idea que la anterior, los parámetros de la plantilla se completarán y se obtendrá el tamaño de la matriz.

La segunda parte está usando esa información para hacer un tipo con un tamaño específico, de ahí el helper type_of_size . Esa parte no es estrictamente necesaria, pero creo que hace que el código sea más fácil de leer. Una char[N] tiene un tamaño igual a N , por lo tanto, podemos abusar de eso para "almacenar" el tamaño de la matriz ... ¡en el tamaño de un tipo en sí mismo!

La tercera parte está consiguiendo ese tamaño con sizeof . En realidad, no evalúa nada, por lo que no necesitamos una definición para la función. Simplemente dice "Si hicieras esto ... el tamaño sería ...". Y el tamaño es nuestro tamaño "almacenado", en la matriz de caracteres.