← SEARCHABLE ARCHIVE
C / C++ · 2026-08-10

C++ de los fundamentos al dominio — Lección 16

Expresar requisitos de plantillas con Concepts y requires

INTERACTIVE READING MODE →

Los artículos de este blog se han escrito con fines didácticos. Pueden contener errores; contrasta la información con el compilador y la biblioteca estándar de tu plataforma.

Las plantillas aplican una regla a muchos tipos, pero un tipo no compatible suele producir errores largos dentro de la implementación. Concepts y requires de C++20 permiten expresar los requisitos en la declaración pública.

El problema de una plantilla sin restricciones

template <typename T>
int GetHealth(const T& value)
{
    return value.Health();
}

La función solo sirve para tipos con Health(), pero la firma no lo indica. El compilador descubre el problema después de instanciar el cuerpo.

Nombrar requisitos con un Concept

#include <concepts>

template <typename T>
concept Damageable = requires(T value, int amount)
{
    { value.Health() } -> std::convertible_to<int>;
    { value.ApplyDamage(amount) } -> std::same_as<void>;
};

template <Damageable T>
void Attack(T& target, int damage)
{
    target.ApplyDamage(damage);
}

Una expresión requires no ejecuta las operaciones; comprueba que la sintaxis y los tipos de resultado sean válidos. El contrato de Attack queda visible antes del cuerpo y el error aparece más cerca de la llamada.

Combinar propiedades del tipo

template <typename T>
concept SmallId = std::integral<T> && (sizeof(T) <= 4);

template <SmallId T>
void WriteId(T id);

Los Concepts combinan type traits y requisitos con operadores lógicos. Las restricciones también participan en la selección de sobrecargas.

void Print(std::integral auto value);
void Print(std::floating_point auto value);

Un auto restringido abrevia una plantilla de función. Si enteros y flotantes tienen significados distintos, las sobrecargas separadas suelen ser más claras que un gran if constexpr.

Una sintaxis válida no garantiza la semántica

Que a < b compile no demuestra que defina un orden coherente. Poder copiar un tipo tampoco garantiza que las copias sean independientes en su comportamiento.

Los Concepts estándar documentan requisitos semánticos además de sintaxis. Un Concept propio necesita un nombre significativo y sus reglas importantes deben probarse.

No restrinjas una plantilla más de lo necesario. Expresa el contrato mínimo real para no rechazar tipos útiles sin mejorar la corrección.