visual studio microsoft español descargar community c++ c++11 c-preprocessor language-lawyer

c++ - studio - ¿Es posible pasar un inicializador entre llaves como un parámetro de macro?



visual studio installer (1)

Puedes usar __VA_ARGS__ :

#define MYMACRO(T,...) literal<T>(__VA_ARGS__);

En caso de que tenga más parámetros, puede usar un direccionamiento indirecto:

#define UNWRAP(...) __VA_ARGS__ #define MYMACRO(T,A) literal<T>(UNWRAP A);

y ahora puedes usar

MYMACRO( long[2], ({1, 2}) )

Respuesta actualizada

También podría, si lo desea, reemplazar los corchetes en la invocación de la macro con los corchetes:

#define BRACED_INIT_LIST(...) {__VA_ARGS__} #define MYMACRO(T,A) literal<T>(BRACED_INIT_LIST A);

y llama

MYMACRO( long[2], (1, 2) )

que es IMHO consistente con los típicos estilos de invocación de macro.

Algunas palabras sobre sus otras preguntas: El preprocesador no sabe nada sobre el lenguaje (C, C ++, C ++ 11) y, por lo tanto, no debería preocuparse por el significado especial de los símbolos. Es un seguimiento de paréntesis, pero casi todo lo demás son solo tokens.

También creo que no es un descuido del comité estándar, ya que el enfoque debería ser hacer que el uso del preprocesador sea superfluo para la mayoría de los casos. ¿Ha considerado otras técnicas (no macro) para implementar MYMACRO ? Además, las soluciones para los casos de uso restantes (como se muestra arriba) son ciertamente posibles.

Finalmente, ciertamente no es un error en GCC ya que el compilador simplemente implementa lo que dice la norma.

Tengo una función que llamo así:

literal<long[2]>({1, 2});

Quiero escribir una macro que se expanda a esta declaración, por ejemplo:

MYMACRO(long[2], {1, 2})

Desafortunadamente, el preprocesador no está al tanto de la compatibilidad con llaves, por lo que ve tres argumentos (el segundo y el tercero son {1 y 2} , respectivamente).

Esta es una limitación conocida del preprocesador, y la solución más simple a menudo es agregar paréntesis adicionales, si es posible, en la invocación de macros.

Pero, en este caso, colocar el inicializador entre llaves entre paréntesis parece cambiar su significado:

literal<long[2]>(({1, 2})); (g++ 4.8) error: left operand of comma operator has no effect [-Werror=unused-value]

¿Es este un error de GCC o correcto por diseño? ¿Hay alguna manera de lograr lo que quiero?

Actualizar

Probablemente debería haber sido más claro en la formulación de las preguntas originales. El preprocesador no ha cambiado en siempre (incluso las macros variadic han sido una extensión GCC durante mucho tiempo). Las soluciones prácticas en este caso son útiles, pero también son muy conocidas y no al punto al que quiero llegar.

Realmente quiero saber si se agregó algo a C ++ 11 para abordar específicamente este problema (¿o fue un descuido?). El manejo peculiar de llaves en las invocaciones de macros parece ser un problema mucho más grande ahora, dado el uso enormemente ampliado de listas con llaves en todo el lenguaje.

Estoy especialmente molesto por el hecho de que poner paréntesis alrededor de una lista de inicializadores entre corchetes cambia la forma en que se analiza cuando se utiliza como un parámetro de función. ¿Hay algún otro parámetro en la invocación de una función que no se pueda poner entre paréntesis? Parece un caso especial al escribir macros que pasan parámetros a funciones.

Realmente espero que alguien pueda señalar que este es un error de GCC, o explicar por qué poner un paréntesis alrededor de una lista de inicializadores entre llaves debe cambiar su significado.