www usuario sesion mexico mathworks log inicio iniciar fabricante empresa descargar c++ arrays c++11

c++ - sesion - matlab usuario



¿Cómo sabe std:: end el final de una matriz? (3)

std::begin y std::end conocen el principio y el final de un container o una array .

Es muy fácil saber el end y el begin de un vector por ejemplo, porque es una clase que proporciona esta información. Pero, ¿cómo sabe el final de una array como la siguiente?

int simple_array[5]{1, 2, 3, 4, 5}; auto beg=std::begin(simple_array); auto en=std::end(simple_array);

std::begin no es tan difícil saber dónde comienza la matriz. Pero, ¿cómo sabe dónde termina? ¿Se almacenará el entero constante 5 alguna parte?

Agradecería si obtuviera una respuesta con información de bajo nivel.


Pero, ¿cómo sabe el final de una matriz?

Utiliza un parámetro de plantilla que no es de tipo para deducir el tamaño de la matriz, que luego se puede usar para generar el puntero final. La firma C ++ 11 de la sección cppreference para std::end es la siguiente:

template< class T, std::size_t N > T* end( T (&array)[N] );

Como señala hvd, dado que se pasa por referencia, esto evita la descomposición de un puntero.

La implementación sería algo similar a:

template< class T, std::size_t N > T* end( T (&array)[N] ) { return array + N ; }

¿El entero constante 5 se almacenará en algún lugar?

5 o N es parte del tipo de matriz y, por lo tanto, N está disponible en tiempo de compilación. Por ejemplo, aplicar sizeof a una matriz nos dará el número total de bytes en la matriz.

Muchas veces vemos una matriz pasada por valor a una función. En ese caso, la matriz se descompone en un puntero para escribir almacenada en la matriz. Entonces ahora se pierde la información del tamaño. Pasar por referencia nos permite evitar esta pérdida de información y extraer el tamaño N del tipo.


es el entero constante 5 se almacenará en algún lugar?

Sí, es parte del tipo de matriz. Pero no, no se almacena en ningún lugar explícitamente. Cuando tengas

int i[5] = { };

el tipo de i es int[5] . La respuesta de Shafik habla sobre cómo se usa esta longitud para implementar el end .

Si tiene C ++ 11, usar constexpr sería la forma más sencilla de hacerlo

template <typename T, size_t N> inline constexpr size_t arrLen(const T (&arr) [N]) { return N; }

Si tiene un compilador anterior a C ++ 11 donde constexpr no está disponible, la función anterior puede no evaluarse en tiempo de compilación. Entonces, en tales situaciones, puede usar esto:

template <typename T, size_t N> char (&arrLenFn(const T (&arr) [N]))[N]; #define arrLen(arr) sizeof(arrLenFn(arr))

Primero declaramos que una función devuelve una referencia a una matriz de N caracteres, es decir, el sizeof esta función ahora sería la longitud de la matriz. Luego tenemos una macro para envolverlo, de modo que sea legible al final de la persona que llama.

Nota: Dos matrices del mismo tipo base pero con diferentes longitudes siguen siendo dos tipos completamente diferentes. int[3] no es lo mismo que int[2] . Sin embargo, la descomposición de la matriz le daría un int* en ambos casos. Leer ¿Cómo uso matrices en C ++? si quieres saber más


Porque está pasando una matriz a std::end , y una matriz tiene el tipo T [N] . std::end puede decir cuándo termina la matriz mirando la N en el tipo.