c++ - template - Argumentos mágicos en plantillas de funciones.
template en c++ pdf (3)
Funciona porque el tipo de a es "matriz de longitud 6 de int " y el tipo de b es "matriz de longitud 1 de int ". El compilador lo sabe, por lo que puede llamar a la función correcta. En particular, la primera llamada llama a la instancia de plantilla cal_size<6>() y la segunda llama a cal_size<1>() , ya que esas son las únicas instancias de plantilla que coinciden con sus respectivos argumentos.
Si intentara llamar a una instancia de plantilla explícita, solo funcionaría si tiene el tamaño correcto, de lo contrario los argumentos no coincidirían. Considera lo siguiente:
cal_size(a); // ok, compiler figures out implicitly that N=6
cal_size<int, 6>(a); // also ok, same result as above
cal_size<int, 5>(a); // ERROR: a is not of type "array of length 5 of int"
En el siguiente código
#include<iostream>
template<typename T,size_t N>
void cal_size(T (&a)[N])
{
std::cout<<"size of array is: "<<N<<std::endl;
}
int main()
{
int a[]={1,2,3,4,5,6};
int b[]={1};
cal_size(a);
cal_size(b);
}
Como era de esperar, el tamaño de ambas matrices se imprime. Pero, ¿cómo se inicializa N automáticamente en el valor correcto del tamaño de la matriz (las matrices se pasan por referencia)? ¿Cómo funciona el código anterior?
cuando declara int a [] = {1,2,3} es lo mismo que (o se reescribirá como) int a [3] = {1,2,3} ya que la función de plantilla recibe un argumento en forma de T a [N], entonces N tendrá un valor de 3.
N no se "inicializa" a nada. No es una variable. No es un objeto. N es una constante en tiempo de compilación. N solo existe durante la compilación. El valor de N , así como la T real, está determinado por el proceso llamado deducción del argumento de la plantilla . Tanto la T como la N se deducen del tipo real del argumento que pasa a su función de plantilla.
En la primera llamada, el tipo de argumento es int[6] , por lo que el compilador deduce que T == int y N == 6 , genera una función separada para eso y la llama. Llamémoslo cal_size_int_6
void cal_size_int_6(int (&a)[6])
{
std::cout << "size of array is: " << 6 << std::endl;
}
Tenga en cuenta que ya no hay T ni N en esta función. Ambos fueron reemplazados por sus valores deducidos reales en el momento de la compilación.
En la primera llamada, el tipo de argumento es int[1] , por lo que el compilador deduce que T == int y N == 1 , genera una función separada para eso también y la llama. Llamémoslo cal_size_int_1
void cal_size_int_1(int (&a)[1])
{
std::cout << "size of array is: " << 1 << std::endl;
}
Lo mismo aqui.
Su main esencialmente se traduce en
int main()
{
int a[]={1,2,3,4,5,6};
int b[]={1};
cal_size_int_6(a);
cal_size_int_1(b);
}
En otras palabras, su plantilla cal_size da nacimiento a dos funciones diferentes (las llamadas especializaciones de la plantilla original), cada una con diferentes valores de N (y T ) codificados en el cuerpo. Así es como funcionan las plantillas en C ++.