tipos sirven que plantillas para los limite int_max definicion c++ templates c++11

sirven - C++ 11: Especialización de funciones de plantilla para tipos enteros



para que sirven los templates c++ (5)

¿Qué tal una forma más sencilla y legible simplemente implementando las diferentes versiones dentro del cuerpo de la función?

template<typename T> void DoSomething(T inVal) { static_assert(std::is_floating_point<T>::value || std::is_integral<T>::value, "Only defined for float or integral types"); if constexpr(std::is_floating_point<T>::value) { // Do something with a float } else if constexpr(std::is_integral<T>::value) { // Do something with an integral } }

No tienes que preocuparte por el rendimiento. Las condiciones son constantes de tiempo de compilación y un compilador de descenso las optimizará. "if constexpr" es c ++ 17 desafortunadamente, pero puede eliminar "constexpr" cuando ambas versiones se compilan sin errores para ambos tipos

Supongamos que tengo una función de plantilla:

template<typename T> void f(T t) { ... }

y quiero escribir una especialización para todos los tipos de enteros primitivos. ¿Cuál es la mejor manera de hacer esto?

Lo que quiero decir es:

template<typename I where is_integral<I>::value is true> void f(I i) { ... }

y el compilador selecciona la segunda versión para los tipos enteros, y la primera versión para todo lo demás?


Puedes usar una plantilla de ayuda que puedes especializar así:

#include <string> #include <iostream> #include <type_traits> template <typename T, bool = std::is_integral<T>::value> struct Foo { static void bar(const T& t) { std::cout << "generic: " << t << "/n"; } }; template <typename T> struct Foo<T, true> { static void bar(const T& t) { std::cout << "integral: " << t << "/n"; } }; template <typename T> static void bar(const T& t) { return Foo<T>::bar(t); } int main() { std::string s = "string"; bar(s); int i = 42; bar(i); return 0; }

salida:

generic: string integral: 42



Utilizar SFINAE

// For all types except integral types: template<typename T> typename std::enable_if<!std::is_integral<T>::value>::type f(T t) { // ... } // For integral types only: template<typename T> typename std::enable_if<std::is_integral<T>::value>::type f(T t) { // ... }

Tenga en cuenta que deberá incluir el valor de retorno completo de std::enable_if incluso para la declaración.


Yo usaría la resolución de sobrecarga. Eso le ahorra tener que usar el truco SFINAE bruto. Desafortunadamente hay muchas áreas donde no puedes evitarlo, pero afortunadamente esta no es una de esas.

template<typename T> void f(T t) { f(t, std::is_integral<T>()); } template<typename T> void f(T t, std::true_type) { // ... } template<typename T> void f(T t, std::false_type) { // ... }