Patrones con enable_if
Restrinja plantillas de la forma clásica
Patrones con enable_if es una lección gratuita de C++ Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C++ Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C++ Academy incluye 4 lecciones en total.
¿Qué es enable_if?
std::enable_if es un pequeño rasgo que define condicionalmente un miembro type. Cuando la condición es verdadera, el tipo existe; cuando es falsa, la plantilla envolvente se elimina mediante SFINAE.
- Se encuentra en
<type_traits>. - Es la herramienta clásica para restringir plantillas.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
doubleIt(T v) { return v * 2; }
int main() {
std::cout << doubleIt(21) << '\n';
return 0;
}Cómo funciona
enable_if<Cond, T>::type es T solo cuando Cond es verdadera. Si es falsa, no existe ningún miembro type, por lo que falla la sustitución.
#include <iostream>
#include <type_traits>
int main() {
std::cout << std::boolalpha;
std::cout << std::is_same<std::enable_if<true, int>::type, int>::value << '\n';
return 0;
}enable_if en el tipo de retorno
La ubicación más habitual es el tipo de retorno. La función solo existe cuando se cumple la condición.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
half(T v) { return v / 2; }
int main() {
std::cout << half(5.0) << '\n';
return 0;
}enable_if como parámetro de plantilla
Otro recurso coloca enable_if en un parámetro de plantilla predeterminado, manteniendo limpio el tipo de retorno.
#include <iostream>
#include <type_traits>
template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
T triple(T v) { return v * 3; }
int main() {
std::cout << triple(4) << '\n';
return 0;
}El atajo enable_if_t
C++14 añadió el alias std::enable_if_t<Cond, T> para poder omitir el código redundante de typename ...::type.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, T>
negate(T v) { return -v; }
int main() {
std::cout << negate(8) << '\n';
return 0;
}Emparejamiento de dos sobrecargas
Proporcione condiciones complementarias de modo que exactamente una sobrecarga sea válida para cualquier tipo, sin ambigüedades.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, const char*>
category() { return "integer"; }
template <typename T>
std::enable_if_t<!std::is_integral<T>::value, const char*>
category() { return "non-integer"; }
int main() {
std::cout << category<int>() << ' ' << category<double>() << '\n';
return 0;
}Combinación de condiciones
Utilice operadores lógicos sobre los valores de los rasgos para expresar restricciones más completas, como «integral y con signo».
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, T>
magnitude(T v) { return v < 0 ? -v : v; }
int main() {
std::cout << magnitude(-12) << '\n';
return 0;
}Restricción de un constructor
Puede colocar enable_if en el parámetro de plantilla de un constructor para permitirlo solo con tipos compatibles.
#include <iostream>
#include <type_traits>
struct Wrapper {
int value;
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
Wrapper(T v) : value(static_cast<int>(v)) {}
};
int main() {
Wrapper w(42);
std::cout << w.value << '\n';
return 0;
}Problema con el argumento de plantilla predeterminado
Dos sobrecargas que solo difieren en un parámetro de plantilla enable_if predeterminado se consideran redefiniciones. Déles formas diferentes; por ejemplo, coloque una condición en el tipo de retorno.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
printKind() { std::cout << "int\n"; }
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
printKind() { std::cout << "float\n"; }
int main() {
printKind<int>();
printKind<double>();
return 0;
}Comparación con los conceptos
Los conceptos de C++20 sustituyen la mayoría de los usos de enable_if con una sintaxis mucho más clara, pero enable_if sigue siendo esencial para el código anterior a C++20 y para algunos casos límite.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T>
square(T v) { return v * v; }
int main() {
std::cout << square(6) << ' ' << square(1.5) << '\n';
return 0;
}Un ejemplo completo
Combine todos los elementos: una familia de funciones que formatea los enteros y los números de coma flotante de forma diferente, seleccionada en tiempo de compilación.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
format(T v) { std::cout << "int[" << v << "]\n"; }
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
format(T v) { std::cout << "float(" << v << ")\n"; }
int main() {
format(10);
format(3.5);
return 0;
}Comprobación rápida
Compruebe su comprensión de enable_if.
Resumen
Ha aprendido los patrones clásicos de enable_if:
- define
::typesolo cuando la condición es verdadera, lo que habilita SFINAE - se coloca en el tipo de retorno o en un parámetro de plantilla predeterminado
- utilice el alias
enable_if_ty combine rasgos con operadores lógicos - los conceptos lo sustituyen en C++20, pero sigue utilizándose ampliamente
Con esto termina el curso de especialización de plantillas y SFINAE.
Aprende C++ con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 51
- Lecciones
- 203
Preguntas frecuentes
¿La lección «Patrones con enable_if» es gratis?
Sí — el texto completo de «Patrones con enable_if» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C++ Academy, actualiza a CoddyKit PRO. El curso de C++ Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Patrones con enable_if»?
Restrinja plantillas de la forma clásica Practicas C++ Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C++ Academy?
No se requiere experiencia previa. C++ Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Patrones con enable_if»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C++ Academy?
Sí. Cada lección de C++ Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Especialización completa
- Especialización parcial
- SFINAE
- Patrones con enable_if