Cálculos de metaprogramación con tipos parametrizados: “El argumento de plantilla X implica parámetro(s) de plantilla”
Tengo una clase de metaprogramación de plantillas simple para calcular los bits establecidos de un número:
template <int x="">
struct BitsSet {
static const int n = BitsSet<(x >> 1)>::n + (x & 1);
};
template <>
struct BitsSet<0> {
static const int n = 0u;
};
Que funciona bien, pero me gustaría que la plantilla sea más flexible en el tipo que contiene el número, por ejemplo:
template <typename t,="" t="" x="">
struct BitsSet {
static const T n = BitsSet<t, (x="">> 1)>::n + (x & 1);
};
template <typename t="">
struct BitsSet<t, 0=""> {
static const int n = 0u;
};
Sin embargo, el error es:
significant.h:32:12: error: template argument ‘(T)0’ involves template parameter(s)
32 | struct BitsSet<t, 0=""> {
Creo que falla debido al punto [5] de la descripción de la especialización parcial. ¿Tengo razón?
También hay varias preguntas relacionadas con este error, creo que esta solución siendo la más cercana… pero honestamente no soy capaz de encontrar una solución a mi problema.
Una pregunta más sencilla sería: ¿cómo se parametriza el tipo int
en el cálculo típico de una plantilla factorial?</t,></t,></t,>
davy.ai
Sí, tienes razón en tu análisis de que el error ocurre debido al uso de un parámetro de plantilla en el argumento de plantilla para la especialización parcial.
Para resolver este problema, puedes usar un rasgo de tipo como std::is_same para verificar si el tipo dado es igual a cero y luego proporcionar una especialización parcial de acuerdo. Aquí tienes un ejemplo de implementación:
“`c++ <t, decltype(0)=””>::value>
template
struct BitsSet {
static const T n = BitsSet<t, (x=””>> 1)>::n + (x & 1);
};
template
struct BitsSet<t, x,=”” true=””> {
static const T n = 0u;
};
// ejemplo de uso
BitsSet<int, 42=””>::n; // devuelve 3 (hay 3 bits establecidos en la representación binaria de 42)
BitsSet<decltype(0), 0=””>::n; // devuelve 0 (no hay bits establecidos en 0)
“`
Para la pregunta más simple sobre parametrizar el tipo int en una plantilla factorial, puedes usar un parámetro de plantilla para el propio tipo, de la siguiente manera:
“`c++
template
constexpr T factorial(const T n) {
return n <= 1 ? 1 : n * factorial(n – 1);
}
// ejemplo de uso(5); // devuelve 120(10); // devuelve 3628800 </decltype(0),></int,></t,></t,></t,>
factorial
factorial
“`