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ómo obtengo un int con un ancho máximo / mínimo?

Me gustaría obtener un int con un tamaño específico para propósitos de vectorización. Algo como int_atleast < 3 /*bytes*/ > debería dar como resultado int32_t, y int_atmost < 5 > debería dar el mismo resultado int32_t. Intenté implementar esto con especialización de plantillas, pero me encontré con un obstáculo porque tendría que especializar cada argumento posible. Pensé en la recursión, pero parece una solución demasiado complicada para algo que probablemente ya esté en el estándar. ¿Qué debo hacer?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Una posible solución a este problema es utilizar el tipo trait std::conditional proporcionado por la biblioteca estándar. Aquí está una implementación de ejemplo:

    “`c++
    #include

    template
    struct int_atleast
    {
    using type = typename std::conditional::type>::type>::type>::type;
    };

    template
    struct int_atmost
    {
    using type = typename std::conditional= 8,
    long long, typename std::conditional
    = 4,
    int, typename std::conditional
    = 2,
    short, typename std::conditional
    = 1,
    char, void>::type>::type>::type>::type;
    };

    // Ejemplo de uso:
    #include
    #include

    int main()
    {
    std::vector<int_atleast<3>::type> vec(5); // vec es std::vector
    std::cout << sizeof(vec[0]) << std::endl; // imprime 4

    std::vector<int_atmost<5>::type> vec2(5); // vec2 es std::vector<int32_t>
    std::cout << sizeof(vec2[0]) << std::endl; // imprime 4
    
    return 0;
    

    }
    “`

    Las plantillas int_atleast e int_atmost se definen como estructuras. Tienen un único argumento de plantilla, que es el ancho deseado del tipo entero en bytes. El alias type dentro de cada estructura se define utilizando std::conditional, lo que nos permite elegir entre dos tipos basados en una condición.

    En la plantilla int_atleast, comenzamos verificando si el ancho deseado es menor o igual a 1 byte. Si lo es, elegimos char como tipo entero. De lo contrario, pasamos a la siguiente condición, que verifica si el ancho es menor o igual a 2 bytes, y así sucesivamente. Finalmente, si ninguna de las condiciones coincide, elegimos void como tipo entero, lo que causará un error de compilación si la plantilla se instancia con un ancho no admitido.

    La plantilla int_atmost funciona de manera similar, pero en sentido contrario. Comenzamos verificando si el ancho deseado es mayor o igual que 8 bytes. Si lo es, elegimos long long como tipo entero. De lo contrario, pasamos a la siguiente condición, que verifica si el ancho es mayor o igual a 4 bytes, y así sucesivamente. Finalmente, si ninguna de las condiciones coincide, elegimos void nuevamente.

    En la función main, demostramos el uso de las plantillas int_atleast e int_atmost creando dos vectores, uno con un ancho mínimo de 3 bytes y otro con un ancho máximo de 5 bytes. Usamos el operador sizeof para imprimir el tamaño de los elementos en cada vector, que debería ser 4, ya que ambas plantillas eligen int32_t en este caso.

    Tenga en cuenta que esta implementación solo admite anchos de enteros que sean potencias de 2. Si necesita admitir anchos de bytes arbitrarios, podría modificar las plantillas para utilizar una búsqueda logarítmica en lugar de una búsqueda lineal, pero esto haría que el código fuera más complicado.</int_atmost<5></int_atleast<3>

Comments are closed.