Un vistazo a las plantillas de función de C++

20200605104652

Un vistazo a las plantillas de función de C++

Las plantillas de funciones son una herramienta para programar funciones versátiles. Y eso es muy bueno, porque cuando una función es muy versátil la podemos volver a usar muchas veces y para muchos propósitos.

Un ejemplo concreto

Supongamos que queremos hacer una plantilla de función que compare cuál de dos números con el mismo tipo de almacenamiento es mayor. De forma específica, queremos utilizar nuestra plantilla con dos tipos de almacenamiento: enteros sin signo de 8 bits uint8_t, y números decimales de 32 bits float.

Si las plantillas no existieran, tendríamos que escribir dos funciones diferentes: una para cada tipo de almacenamiento (listado 1). Pero con las plantillas, podemos escribir una sola función (listado 2).

#include <cstdio>
#include <cstdint>

uint8_t cual_es_mayor_uint8(uint8_t x, uint8_t y)
{
        return (x > y) ? x : y;
}

float cual_es_mayor_float(float x, float y)
{
        return (x > y) ? x : y;
}

int32_t main()
{
        float a = 1.234;
        float b = 5.678;
        uint8_t c = 7;
        uint8_t d = 42; 

        printf("%f\n", cual_es_mayor_float(a, b));
        printf("%u\n", cual_es_mayor_uint8(c, d));

        return 0;
}


Listado 1. (programa_con_plantillas) Si no utilizamos plantillas, necesitaríamos utilizar dos funciones diferentes: una para cada tipo de dato.

#include <cstdio>
#include <cstdint>

template <typename TIPO_DE_ALMACENAMIENTO>
TIPO_DE_ALMACENAMIENTO cual_es_mayor(
    TIPO_DE_ALMACENAMIENTO x,
    TIPO_DE_ALMACENAMIENTO y
)
{
    return (x > y) ? x : y;
}

int32_t main()
{
        float a = 1.234;
        float b = 5.678;
        uint8_t c = 7;
        uint8_t d = 42; 

        printf("%f\n", cual_es_mayor<float>(a, b));
        printf("%u\n", cual_es_mayor<uint8_t>(c, d));

        return 0;
}

Listado 2. (programa_sin_plantillas) Con una sola plantilla podemos sustituir las dos funciones cual_es_mayor_float y cual_es_mayor_uint8 que aparecen en el listado 1.

Las plantillas de funciones pueden tener más de un parámetro de plantilla. En el caso del código del listado 2, la plantilla de función cual_es_mayor solamente tiene un parámetro de plantilla: un tipo de almacenamiento referido por el nombre TIPO_DE_ALMACENAMIENTO. Pero el ejemplo del listado 3 tiene dos parámetros de plantilla.

template <typename TIPO_DE_ALMACENAMIENTO, uint32_t REFERENCIA>
bool mayor_que(
    TIPO_DE_ALMACENAMIENTO x
)
{
    return x > (TIPO_DE_ALMACENAMIENTO) REFERENCIA;
}

Listado 3. Plantilla de función con dos parámetros de plantilla.

Las plantillas aumentan el tamaño del programa

Las plantillas pueden incrementar el tamaño del programa final. Porque el compilador generará una nueva función por cada combinación de parámetros de plantilla que utilicemos en el código. Por ejemplo, utilizando el compilador g++ para compilar el código del listado 2, encontré que el compilador creó dos funciones desde la plantilla cual_es_mayor. Veamos el listado 4.

$ objdump -t programa_con_plantillas | grep cual_es_mayor
00000000000011f9  w    F .text	0000000000000027              _Z13cual_es_mayorIhET_S0_S0_
00000000000011ce  w    F .text	000000000000002b              _Z13cual_es_mayorIfET_S0_S0_

$ objdump -t programa_sin_plantillas | grep cual
0000000000001149 g     F .text	0000000000000027              _Z19cual_es_mayor_uint8hh
0000000000001170 g     F .text	000000000000002b              _Z19cual_es_mayor_floatff

Listado 4. Entradas de las tablas de símbolos de programa_con_plantillas y programa_sin_plantillas cuyos nombres contienen cual_es_mayor.

Más plantillas

El lenguace C++, además de soportar plantillas de función, también soporta plantillas de clases, plantillas de plantillas, entre otras. Y de hecho, su librería estándar contiene una librería de plantillas frecuentemente referida como STL (por su nombre en inglés Standard Template Library). Algunas de las plantillas populares de esta librería son vector, hash_map, y queue.

Comentarios

Entradas más populares de este blog

10 palabras valen más que una imagen - 20240526223027

20220214085408 - El reto de hacer amistades nuevas en la vida adulta

20220208192042 - Los modelos abstractos: sólo una cara del diamante