Las plantillas con parámetros por defecto son un mecanismo potente de programación genérica en C++.
Historia del tema:
Las plantillas fueron el punto de partida de la biblioteca STL. Más tarde, se introdujo la posibilidad de especificar valores por defecto para los parámetros de funciones y clases plantilla, con el fin de hacer las plantillas más universales y mantener la extensibilidad del código.
Problema:
Pueden surgir conflictos poco evidentes cuando hay sobrecargas de funciones normales y plantillas, así como ambigüedades en las especializaciones. Los parámetros por defecto en las plantillas pueden aumentar la flexibilidad, pero a menudo conducen a errores de compilación confusos.
Solución:
Es mejor minimizar el número de valores por defecto en las plantillas, especialmente si hay intersecciones con las versiones no plantilla. En la llamada a funciones, se prefiere una coincidencia exacta con la función normal en lugar de la plantilla.
Ejemplo de código:
template<typename T = int> T multiply(T a, T b = T(2)) { return a * b; } int multiply(int a, int b) { return a + b; }
La llamada multiply(5, 4) elegirá la función int multiply(int, int), mientras que la llamada multiply<>(5) invocará la plantilla, y b tomará el valor 2.
Características clave:
¿Se pueden declarar parámetros por defecto en una nueva definición de una función plantilla?
No, el valor por defecto solo se puede especificar en un lugar (generalmente en la declaración), de lo contrario habrá un error de compilación.
¿Qué sucede ante una ambigüedad entre una plantilla y una función no plantilla? ¿Cómo elige el compilador qué invocar?
El compilador siempre dará preferencia a la función no plantilla si se ajusta exactamente a los argumentos. La plantilla solo se invocará si no hay coincidencia exacta.
¿Se pueden especificar valores por defecto para parámetros que no son tipos de parámetro de plantilla (por ejemplo, para números)?
Sí, por ejemplo:
template<typename T, int N = 8> class Array { T data[N]; };
Caso negativo
Se han declarado tanto una función plantilla como una no plantilla con parámetros coincidentes y valores por defecto. En un módulo, la llamada funciona como se esperaba, mientras que en otro se elige inesperadamente la versión incorrecta de la función.
Pros:
Contras:
Caso positivo
Para configuraciones que se intersectan, se han declarado nombramientos diferentes y explícitos para las funciones plantilla y no plantilla, con valores por defecto solo en una de las versiones.
Pros:
Contras: