Lección 9 · 9 de 20
Plantillas de funciones · C++
Escriba una sola función de C++ para muchos tipos con template: el mayor de una lista de números, palabras o versiones, y un límite genérico.

Una plantilla de función es un molde: template <typename T> dice que T es un tipo que se decidirá al usarla. largest busca el mayor elemento de un std::vector<T> sin saber si contiene enteros, cadenas o cualquier otra cosa.
Al llamar a largest(std::vector<int>{12, 47, 33}), el compilador deduce que T es int y genera una versión para enteros. Con el vector de std::string genera otra, que compara por orden alfabético: «zucchini» es la última. Cada tipo produce su propia función, sin coste al ejecutar.
Lo único que largest le pide a T es que se pueda comparar con <. Version define operator< (primero el número mayor y, si empata, el menor), así que la plantilla también funciona con ella y encuentra la 2.0. Si un tipo no cumple lo que pide la plantilla, el error aparece al compilar.
clampTo encaja un valor entre un mínimo y un máximo: el volumen 130 se queda en 100 y la calefacción a 3,5 grados sube a 5. Los tres parámetros son del mismo T, por eso clampTo(7, 0.5, 6.5) no compila: T no puede ser int y double a la vez. Con clampTo<double>(...) se indica el tipo explícitamente y el 7 se convierte en 7.0.
Código · main.cpp
#include <iostream>#include <string>#include <vector>// One template, many types: the compiler deduces T from the arguments.template <typename T>T largest(const std::vector<T>& items) { T best = items[0]; for (const T& x : items) if (best < x) best = x; // the only thing T needs: operator< return best;}template <typename T>T clampTo(T value, T low, T high) { return value < low ? low : (high < value ? high : value); }// Any type with operator< works, including our own.struct Version { int major, minor; bool operator<(const Version& o) const { return major != o.major ? major < o.major : minor < o.minor; }};int main() { std::cout << "Highest score: " << largest(std::vector<int>{12, 47, 33}) << "\n"; std::cout << "Last word: " << largest(std::vector<std::string>{"pear", "apple", "zucchini"}) << "\n"; Version v = largest(std::vector<Version>{{1, 4}, {2, 0}, {1, 12}}); std::cout << "Latest version: " << v.major << "." << v.minor << "\n"; std::cout << "Volume: " << clampTo(130, 0, 100) << "\n"; std::cout << "Heating: " << clampTo(3.5, 5.0, 30.0) << "\n"; // clampTo(7, 0.5, 6.5) fails: T cannot be int and double. Say it explicitly: std::cout << "Explicit T: " << clampTo<double>(7, 0.5, 6.5) << "\n";}Salida · c++ -std=c++17 main.cpp -o main && ./main
Highest score: 47 Last word: zucchini Latest version: 2.0 Volume: 100 Heating: 5 Explicit T: 6.5
Para recordar
template <typename T>delante de una función la convierte en plantilla.- El compilador deduce
Tde los argumentos y genera una versión por tipo. - La plantilla funciona con cualquier tipo que tenga las operaciones que usa.
funcion<Tipo>(...)fija el tipo a mano cuando la deducción no basta.- Las plantillas se escriben enteras, con su cuerpo, antes de usarlas (normalmente en un
.h).
Ejercicio
Escriba una plantilla countAbove(const std::vector<T>& items, T limit) que cuente cuántos elementos son mayores que limit, y pruébela con notas (int) y con temperaturas (double).