tipos template programar plantillas plantilla funciones con ats c++ templates

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 ++.