Saltar al contenido

Preprocesador C++ __VA_ARGS__ número de argumentos

Lola, miembro de este gran equipo, nos ha hecho el favor de crear esta crónica ya que controla muy bien el tema.

Solución:

Usualmente uso esto macro para encontrar una serie de parámetros:

#define NUMARGS(...)  (sizeof((int[])__VA_ARGS__)/sizeof(int))

Ejemplo completo:

#include 
#include 
#include 

#define NUMARGS(...)  (sizeof((int[])__VA_ARGS__)/sizeof(int))
#define SUM(...)  (sum(NUMARGS(__VA_ARGS__), __VA_ARGS__))

void sum(int numargs, ...);

int main(int argc, char *argv[]) 

    SUM(1);
    SUM(1, 2);
    SUM(1, 2, 3);
    SUM(1, 2, 3, 4);

    return 1;


void sum(int numargs, ...) 
    int     total = 0;
    va_list ap;

    printf("sum() called with %d params:", numargs);
    va_start(ap, numargs);
    while (numargs--)
        total += va_arg(ap, int);
    va_end(ap);

    printf(" %dn", total);

    return;

Es un código C99 completamente válido. Sin embargo, tiene un inconveniente: no puede invocar el macro SUM() sin params, pero GCC tiene una solución para esto – ver aquí.

Entonces, en el caso de GCC, debe definir macros como esta:

#define       NUMARGS(...)  (sizeof((int[])0, ##__VA_ARGS__)/sizeof(int)-1)
#define       SUM(...)  sum(NUMARGS(__VA_ARGS__), ##__VA_ARGS__)

y funcionará incluso con una lista de parámetros vacía

En realidad, esto depende del compilador y no es compatible con ningún estándar.

Aquí, sin embargo, tienes un macro implementación que hace la cuenta:

#define PP_NARG(...) 
         PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) 
         PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( 
          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, 
         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, 
         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, 
         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, 
         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, 
         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, 
         _61,_62,_63,N,...) N
#define PP_RSEQ_N() 
         63,62,61,60,                   
         59,58,57,56,55,54,53,52,51,50, 
         49,48,47,46,45,44,43,42,41,40, 
         39,38,37,36,35,34,33,32,31,30, 
         29,28,27,26,25,24,23,22,21,20, 
         19,18,17,16,15,14,13,12,11,10, 
         9,8,7,6,5,4,3,2,1,0

/* Some test cases */


PP_NARG(A) -> 1
PP_NARG(A,B) -> 2
PP_NARG(A,B,C) -> 3
PP_NARG(A,B,C,D) -> 4
PP_NARG(A,B,C,D,E) -> 5
PP_NARG(1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3) -> 63

Si está utilizando C++ 11 y necesita el valor como una constante de tiempo de compilación de C++, una solución muy elegante es esta:

#include 

#define MACRO(...) 
    std::cout << "num args: " 
    << std::tuple_size::value 
    << std::endl;

Tenga en cuenta: el conteo ocurre completamente en tiempo de compilación, y el valor se puede usar siempre que se requiera un entero en tiempo de compilación, por ejemplo, como un parámetro de plantilla para std:array.

Acuérdate de que puedes optar por la opción de aclarar tu experiencia si atinaste tu atasco .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *