22 votos

¿Qué significa este código de C++?

El código siguiente devuelve el tamaño de una matriz asignada de pila:

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

pero yo no puedo envolver mi cabeza alrededor de la sintaxis. Especialmente la T (&) [size] parte...

23voto

Maxim Yegorushkin Puntos 29380

pero no puedo envolver mi cabeza alrededor de la sintaxis. Especialmente la T (&) [size] parte...

Esa parte es una referencia a una matriz. No es la "derecha-izquierda de la regla" para descifrar cualquier C y C++ las declaraciones.

Debido a que la función de las plantillas de deducir de la plantilla de tipos de argumentos de la función proporcionados argumentos de lo que esta función de la plantilla que hace es deducir el tipo y el recuento de elementos de una matriz y devuelve el recuento.

Funciones no puede aceptar la matriz de tipos por valor, sino sólo por el puntero o referencia. La referencia que se utiliza para evitar la conversión implícita de una matriz para el puntero a su primer elemento (aka, la matriz de descomposición):

void foo(int*);

int x[10];
int* p = x; // array decay
foo(x);     // array decay again

Matriz de descomposición destruye el tipo original de la matriz y, por tanto, el tamaño de la misma se pierde.

Nota, porque es una llamada a una función en C++03, el valor de retorno no es una compilación de constante de tiempo (es decir, el valor de retorno no puede ser utilizado como un argumento de plantilla). En C++11 de la función pueden ser marcados con constexpr a devolver una compilación constante de tiempo:

template<typename T, size_t size>
constexpr size_t siz(T(&)[size]) { return size; }

Para obtener el elemento de la matriz de conteo como una constante en tiempo de compilación en C++03 una forma ligeramente diferente puede ser utilizado:

template<class T, size_t size>
char(&siz(T(&)[size]))[size]; // no definition required

int main()
{
    int x[10];
    cout << sizeof siz(x) << '\n';
    double y[sizeof siz(x)]; // use as a compile time constant 10
}

En el anterior declara una plantilla de función con la misma referencia-a-una-matriz argumento, pero con el tipo de valor devuelto de char(&)[size] (esto es donde la "derecha-izquierda de la regla" puede ser apreciado). Tenga en cuenta que la llamada a la función nunca sucede en tiempo de ejecución, esta es la razón por la definición de la plantilla de función siz es innecesario. sizeof siz(x) es básicamente diciendo: "¿cuál sería el tamaño del valor de retorno si siz(x) fueron llamados".

El viejo C/C++ manera de hacer llegar el recuento de elementos de una matriz como una compilación de constante de tiempo es:

#define SIZ(arr) (sizeof(arr) / sizeof(*(arr)))

7voto

Flexo Puntos 39273

T (&) [size] es una referencia a una matriz. Debe ser una referencia porque el siguiente programa no es legal:

#include <iostream>

int sz(int *) { std::cout << "wtf?" << std::endl; return 0; }


int sz(int [4]) { std::cout << "4" << std::endl; return 0; }

int main() {
  int test[4];
  sz(test);
}

Este programa falla al compilar con:

test.cc: In function ‘int sz(int*)':
test.cc:6:5: error: redefinition of ‘int sz(int*)'
test.cc:3:5: error: ‘int sz(int*)' previously defined here

porque int sz(int [4]) es idéntica a int sz(int *).

Los paréntesis son necesarios para eliminar la ambigüedad de aquí porque T& [size] se ve como un array de referencias que es ilegal.

Normalmente, si el parámetro no era anónimo habría que escribir:

template<typename T, int size>
int sz(T (&arr) [size])

Para dar a la matriz el nombre arr. En este caso, a pesar de todo su código de ejemplo importaba era el deducirse tamaño y, por tanto, el anónimo argumento evita las advertencias acerca de sin utilizar argumentos.

4voto

MäxL Puntos 100

It´s una función que se convierte en un typename (plantillas pueden usarse con diferentes typenames) y un tamaño desde el exterior. Luego devuelve este tamaño.

Pila de funciones suelen ser size , que es un número entero que le muestra el tamaño de la pila-solicitar esta función. La & significa sólo que el tamaño de pila T las pruebas.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X