es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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,>

Tags:  , ,

Answer

  1. Avatar for 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++
    template <t, decltype(0)=””>::value>
    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
    factorial(5); // devuelve 120
    factorial(10); // devuelve 3628800
    “`
    </decltype(0),></int,></t,></t,></t,>

Comments are closed.