Bienvenidos sean a este post, hoy veremos uno de los tipos de parametros en las templates.
Los parametros de un template son los que estan entre el signo mayor y menor al momento de definirlo. De estos tendremos varios tipos, y hoy veremos uno de ellos. Los parametros del titulo son aquellos que hacen referencia a valores constantes al momento de compilacion, tales como enteros y punteros, que referencian entidades estaticas. Vamos a aplicarlo en un ejemplo, para ello analicemos el siguiente codigo:
#include <iostream>
template <int N>
class V
{
public:
V(int inicio) {
for(int i = 0; i < N; ++i) { a[i] = inicio; }
}
int a[N];
};
int main()
{
V<5> x(1);
x.a[2] = 10;
for( auto &e : x.a)
std::cout << e << std::endl;
return 0;
}
Por ejemplo, vean el template que aplicamos. En lugar de usar class o typename le pasamos el tipo de dato que usaremos. En la clase, tenemos un constructor que recibira un valor. En este mediante un bucle iniciaremos todos los campos de un array con el valor recibido. Por fuera, tenemos el array que iniciaremos. El valor del tamaño es el recibido mediante el template. En el main, creamos un objeto de esta clase y observen que le pasamos un valor de tipo int para establecer el tamaño del array y el valor que le asignaremos. Lo siguiente es establecer un valor para la tercer posicion del array en el objeto. Por ultimo, pasamos por todo el array y mostramos los valores en la consola. Compilemos y veamos como es la salida:
$ ./plantilla
1
1
10
1
1
$
Como pueden ver se realizo toda la tarea solicitada. Como pueden ver solo podemos pasar un tipo de dato para nuestro template. Y este puede ser utilizado de una manera similar. Analicemos el siguiente ejemplo:
#include <iostream>
template <const char* msj>
void mostrar()
{
std::cout << msj;
}
extern const char texto1[] = "tinchicus.com";
constexpr char texto2[] = " es un gran sitio ";
extern const char* texto3 = "para aprender.";
int main()
{
mostrar<texto1> ();
mostrar<texto2> ();
mostrar<texto3> ();
std::cout << std::endl;
return 0;
}
Ahora veremos lo mismo pero aplicado a una funcion. En el parametro usaremos una constante de tipo char. La funcion mostrara el valor que pasaremos como parametro. Lo siguiente sera definir tres constantes del tipo char con distintos textos. En dos casos usaremos a extern para indicar que es una variable externa y que se ha creado una instancia de la plantilla en otro lugar, y le indicara al compilador que puede reutilizar la otra creacion de instancias. Y en un caso usamos a constexpr para verificar y pasar que es una expresion constante, sobre este hablamos en este post. En el main, haremos tres llamados con las tres constantes anteriores. Compilemos y veamos como es la salida:
$ g++ plantilla.cpp -o plantilla
plantilla.cpp:11:20: warning: ‘texto3’ initialized and declared ‘extern’
11 | extern const char* texto3 = "para aprender.";
| ^~~~~~
plantilla.cpp: In function ‘int main()’:
plantilla.cpp:17:25: error: no matching function for call to ‘mostrar<texto3>()’
17 | mostrar<texto3> ();
| ~~~~~~~~~~~~~~~~^~
plantilla.cpp:4:6: note: candidate: ‘template<const char* msj> void mostrar()’
4 | void mostrar()
| ^~~~~~~
plantilla.cpp:4:6: note: template argument deduction/substitution failed:
plantilla.cpp:17:25: error: ‘texto3’ is not a valid template argument because ‘texto3’ is a variable, not the address of a variable
17 | mostrar<texto3> ();
| ~~~~~~~~~~~~~~~~^~
$
Fallo en la compilacion porque texto3 no es una constante sino que el puntero es constante pero los datos son variables. Como mencionamos al inicio, los datos en este ttipo de parametro deben ser constantes. Por lo tanto, debemos modificar a la constante texto3 de la siguiente manera:
extern const char texto3[] = "para aprender.";
Al estar definida como la primer constante, volvera a ser una constante y podemos ejecutarlo correctamente. Compilemos y veamos como es la salida:
$ ./plantilla
tinchicus.com es un gran sitio para aprender.
$
Como podemos ver ahora funciono pero tambien podemos cometer el mismo error con la siguiente constante:
const char* texto1[] = "tinchicus.com";
Esto es principalmente porque no tenemos un linkage exterior, por esta razon necesitamos usar a extern pero tampoco debemos usar a un puntero porque la constante sera el puntero pero no donde estaran los datos. Este es el primero de los parametros de un template, en los proximos posts veremos los otros que disponemos.
En resumen, hoy hemos visto a parametros non-type de templates, que es, como se compone, para que sirve, como se aplica, y un par de ejemplos para ver como trabaja. Espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donatión
It’s for site maintenance, thanks!
$1.50
