Tal vez lo que está buscando sea sobrecargas de funciones, parámetros predeterminados, plantillas variadas o posiblemente el idioma del parámetro nombrado
smoothware
Actualice su respuesta seleccionada a las que han votado mucho a favor con soluciones reales, no a las que han votado menos a favor que diceNo you can't
Albert Renshaw
Respuestas:
156
He aquí una forma de hacerlo. Utiliza la lista de argumentos dos veces, primero para formar el nombre de la macro auxiliar y luego para pasar los argumentos a esa macro auxiliar. Utiliza un truco estándar para contar el número de argumentos de una macro.
Esto es genial, pero no creo que funcione si solo hiciera PRINT_STRING. En ese caso, no habría una impresión predeterminada (y ese es el caso que quiero utilizar). Todavía +1 por realmente genial.
Cenoc
2
funciona para mí en gcc (¡y es muy inteligente!) :-) pero no funciona para mí en Visual Studio :-(
Tim Gradwell
3
@TimGradwell: se debe a un error en el compilador de MSVC que han reconocido pero que no han solucionado en casi una década. Sin embargo, existen soluciones alternativas .
BeeOnRope
Inteligente, pero no funciona para argumentos de macro variadic opcionales debido a la cosa de 'expulsar' que está sucediendo en 'GET_4th_ARG'.
motor de búsqueda27 de
¿Es eso PRINT_STRING_MACRO_CHOOSERsiquiera necesario? ¿Puedo reemplazarlo con su cuerpo interno directamente y llamar a todo esto con (__VA_ARGS__)?
Herrgott
85
Con gran respeto a Derek Ledbetter por su respuesta, y con disculpas por revivir una vieja pregunta.
Obtener una comprensión de lo que estaba haciendo y retomar en otro lugar la capacidad de preceder al __VA_ARGS__con ##me permitió encontrar una variación ...
// The multiple macros that you would need anyway [as per: Crazy Eddie]#define XXX_0()<code for no arguments>#define XXX_1(A)<code for one argument>#define XXX_2(A,B)<code for two arguments>#define XXX_3(A,B,C)<code for three arguments>#define XXX_4(A,B,C,D)<code for four arguments>// The interim macro that simply strips the excess and ends up with the required macro#define XXX_X(x,A,B,C,D,FUNC,...) FUNC
// The macro that the programmer uses #define XXX(...) XXX_X(,##__VA_ARGS__,\
XXX_4(__VA_ARGS__),\
XXX_3(__VA_ARGS__),\
XXX_2(__VA_ARGS__),\
XXX_1(__VA_ARGS__),\
XXX_0(__VA_ARGS__)\
)
Para los no expertos como yo que se topan con la respuesta, pero no pueden ver cómo funciona, pasaré por el procesamiento real, comenzando con el siguiente código ...
XXX();
XXX(1);
XXX(1,2);
XXX(1,2,3);
XXX(1,2,3,4);
XXX(1,2,3,4,5);// Not actually valid, but included to show the process
Puede obtener un error de compilación claro si convierte el argumento seleccionado, que se supone que es un nombre MACRO, en una cadena usando # (el signo de almohadilla) y compara sus primeros n caracteres con el prefijo esperado y, si no hay coincidencia, imprime un informativo error.
AturSams
1
Vaya, no sé si esto funciona, ¡pero al menos es muy creativo!
Expiación limitada
4
¿Por qué el primer argumento siempre está vacío? por qué no podemos simplemente omitirlo: XXX_X(,##__VA_ARGS__,` ... XXX_X (, XXX_4 (), XXX_3 (), XXX_2 (), XXX_1 (), XXX_0 ()); `
rahman
2
El primer argumento vacío (coma) es importante. ## __ VA_ARGS__ si está precedido por una coma, elimina la coma si ## __ VA_ARGS__ se expande a nada. Puede verlo en el ejemplo "Se convierte en ...", ya que la primera línea (sin argumentos) tiene solo 6 parámetros, pero el resto obtiene 7. Este truco asegura que la situación sin argumentos funciona
David Sorkovsky
@Eric: se debe a un error en los compiladores de microsoft, pero puede ver esta pregunta para encontrar soluciones.
BeeOnRope
31
Las macros de C ++ no han cambiado de C. Dado que C no tenía sobrecarga ni argumentos predeterminados para las funciones, ciertamente no los tenía para las macros. Entonces, para responder a su pregunta: no, esas funciones no existen para las macros. Su única opción es definir múltiples macros con diferentes nombres (o no usar macros en absoluto).
Como nota al margen: en C ++ generalmente se considera una buena práctica alejarse de las macros tanto como sea posible. Si necesita funciones como esta, es muy probable que esté abusando de las macros.
Tenga en cuenta que la razón por la que es imposible "sobrecargar" macros es porque no tienen ningún tipo inherente. Las macros simplemente se expanden.
mk12
2
Aunque yo uso macros lo menos posible, he encontrado que la depuración a través de la salida de rastreo se pone un poco más fácil con cosas como __FILE__y __LINE__y tal ...
La compilación condicional y la depuración / registro es el dominio donde las macros son realmente útiles y legítimas. Todo programador serio lo sabe. Lo que es una buena práctica es evitar el uso de macros para definir constantes y hacer algunas cosas locas de codificación de nivel C para crear plantillas de contenedor. Me gustaría que C ++ también agregara más funciones a las macros. Son ortogonales a las plantillas. Lo mejor, por supuesto, serían los codelets que me permitan agregar generadores al compilador para el lenguaje específico del dominio (aspectos).
Lothar
1
También creo que esta no es una buena respuesta, porque una macro es algo completamente diferente a cualquier opción del lenguaje C ++, porque se manejará ANTES del compilador. Entonces puede hacer otras cosas, y ningún compilador o enlazador debe optimizar el código, porque tal vez no sea para optimizar.
alabamajack
26
Con el mayor respeto a Derek Ledbetter , David Sorkovsky , Syphorlate por sus respuestas, junto con el ingenioso método para detectar macro argumentos vacíos de Jens Gustedt en
finalmente salgo con algo que incorpora todos los trucos, para que la solución
Utiliza solo macros C99 estándar para lograr la sobrecarga de funciones, sin extensión GCC / CLANG / MSVC involucrada (es decir, deglución de coma por la expresión específica , ##__VA_ARGS__para GCC / CLANG, y deglución implícita por ##__VA_ARGS__para MSVC). Así que siéntase libre de pasar lo que falta --std=c99a su compilador si lo desea =)
Funciona para cero argumentos , así como para un número ilimitado de argumentos , si lo expande aún más para satisfacer sus necesidades
Funciona razonablemente multiplataforma , al menos probado para
GNU / Linux + GCC (GCC 4.9.2 en CentOS 7.0 x86_64)
GNU / Linux + CLANG / LLVM , (CLANG / LLVM 3.5.0 en CentOS 7.0 x86_64)
OS X + Xcode , (XCode 6.1.1 en OS X Yosemite 10.10.1)
Windows + Visual Studio , (Visual Studio 2013 Update 4 en Windows 7 SP1 de 64 bits)
Para los perezosos, simplemente salte al último de esta publicación para copiar la fuente. A continuación se muestra la explicación detallada, que con suerte ayuda e inspira a todas las personas que buscan __VA_ARGS__soluciones generales como yo. =)
Así es como funciona. En primer lugar definir la "función" visible para el usuario sobrecargado, lo nombré create, y la definición de función real relacionada realCreate, y las definiciones de macro con diferente número de argumentos CREATE_2, CREATE_1, CREATE_0, como se muestra a continuación:
En MACRO_CHOOSER(__VA_ARGS__)última instancia, la parte se resuelve en los nombres de las definiciones de macro y la segunda (__VA_ARGS__)parte comprende sus listas de parámetros. Entonces, la llamada de un usuario a se create(10)resuelve en CREATE_1(10), la CREATE_1parte proviene de MACRO_CHOOSER(__VA_ARGS__)y la (10)parte proviene del segundo (__VA_ARGS__).
El MACRO_CHOOSERutiliza el truco de que, si __VA_ARGS__está vacía, la siguiente expresión se concatena en una llamada a la macro válida por el preprocesador:
NO_ARG_EXPANDER __VA_ARGS__ ()// simply shrinks to NO_ARG_EXPANDER()
Ingeniosamente, podemos definir esta macro llamada resultante como
#define NO_ARG_EXPANDER(),,CREATE_0
Tenga en cuenta las dos comas, se explicarán pronto. La siguiente macro útil es
Como sugiere el nombre de la macro, más adelante contaremos el número de argumentos. Aquí viene otro truco: el preprocesador solo realiza un simple reemplazo de texto. Infiere el número de argumentos de una llamada de macro simplemente del número de comas que ve entre paréntesis. Los "argumentos" reales separados por comas no necesitan tener una sintaxis válida. Pueden ser cualquier texto. Es decir, en el ejemplo anterior, NO_ARG_EXPANDER 10 ()se cuenta como 1 argumento para la llamada intermedia. NO_ARG_EXPANDER 20y 20 ()se cuentan como 2 argumentos para la última llamada respectivamente.
Si usamos las siguientes macros auxiliares para expandirlas aún más
El seguimiento ,posterior CREATE_1es una solución alternativa para GCC / CLANG, suprimiendo un error (falso positivo) que dice eso ISO C99 requires rest arguments to be usedcuando se pasa -pedantica su compilador. El FUNC_RECOMPOSERes un trabajo en torno a MSVC, o que no se puede contar el número de argumentos (es decir, comas) dentro del paréntesis de las llamadas macro correctamente. Los resultados se resuelven además a
Como el ojo de águila que puede haber visto, el último único paso que necesitamos es emplear un truco de conteo de argumentos estándar para finalmente elegir los nombres de la versión de macro deseados:
#define FUNC_CHOOSER(_f1, _f2, _f3,...) _f3
que resuelve los resultados a
CREATE_0();
CREATE_1(10);
CREATE_2(20,20);
y ciertamente nos da las llamadas de función reales deseadas:
Aunque complicado, feo, agobiante al desarrollador de API, llega una solución para sobrecargar y configurar parámetros opcionales de funciones C / C ++ para nosotros los locos. El uso de las API sobrecargadas resultantes se vuelve muy agradable y agradable. =)
Si existe alguna posible simplificación adicional de este enfoque, hágamelo saber en
Para cualquiera que busque dolorosamente alguna solución VA_NARGS que funcione con Visual C ++. La siguiente macro funcionó para mí perfectamente (¡también con cero parámetros!) En visual c ++ express 2010:
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,N,...) N
#define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
#define VA_NARGS(...)bool(#__VA_ARGS__)?(VA_NUM_ARGS_IMPL_((__VA_ARGS__,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
Si desea una macro con parámetros opcionales, puede hacer:
Estoy recibiendounresolved external symbol _bool referenced in function _main
Avidan Borisov
sí, eso puede suceder en algunos casos. debe tener en cuenta que bool (#__ VA_ARGS__)? es diferente a las otras macros ya que se está evaluando en tiempo de ejecución. Sin embargo, dependiendo de su caso, puede omitir esa parte del código.
Syphorlate
2
De hecho, terminé con pastebin.com/H3T75dcn, que funciona perfectamente (0 argumentos también).
Avidan Borisov
Gracias por el enlace, y sí, también puede hacerlo usando sizeof, pero para mí eso no funcionó en algunos casos, pero el principio es el mismo (evaluación booleana).
Syphorlate
¿Podría dar algunos ejemplos en los que falla?
Avidan Borisov
7
gcc/ g++admite macros varargs, pero no creo que esto sea estándar, así que úselo bajo su propio riesgo.
Son estándar en C99 y también se están agregando a C ++ 0x.
greyfade
5
#include<stdio.h>#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#define PP_CONCAT(a,b) PP_CONCAT_(a,b)#define PP_CONCAT_(a,b) a ## b#define THINK(...) PP_CONCAT(THINK_, PP_NARG(__VA_ARGS__))(__VA_ARGS__)#define THINK_0() THINK_1("sector zz9 plural z alpha")#define THINK_1(location) THINK_2(location,42)#define THINK_2(location,answer) THINK_3(location, answer,"deep thought")#define THINK_3(location,answer,computer) \
printf ("The answer is %d. This was calculated by %s, and a computer to figure out what this"" actually means will be build in %s\n",(answer),(computer),(location))int
main (int argc,char*argv[]){
THINK ();/* On compilers other than GCC you have to call with least one non-default argument */}
DESCARGO DE RESPONSABILIDAD: Mayormente inofensivo.
hay un error en su código. por favor haz :%s/MY_MACRO_/THINK_/g:)
João Portela
Además, no funcionó con cero argumentos usando g ++i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
João Portela
1
No existen argumentos cero para las macros de variadiac, ya que el token vacío es un marcador de posición válido.
Paul Fultz II
3
Eso no es realmente para lo que está diseñado el preprocesador.
Dicho esto, si desea entrar en el área de la programación de macros que desafía seriamente con un mínimo de legibilidad, debería echar un vistazo a la biblioteca del preprocesador Boost . Después de todo, ¡no sería C ++ si no hubiera tres niveles de programación completamente compatibles con Turing (preprocesador, metaprogramación de plantillas y nivel básico C ++)!
Como gran fanático de los horribles monstruos macro, quería ampliar la respuesta de Jason Deng y hacerla realmente utilizable. (Para bien o para mal). El original no es muy agradable de usar porque necesita modificar la gran sopa de letras cada vez que desea crear una nueva macro y es aún peor si necesita una cantidad diferente de argumentos.
Así que hice una versión con estas características:
0 caso de argumento funciona
1 a 16 argumentos sin modificaciones a la parte desordenada
Fácil de escribir más funciones macro
Probado en gcc 10, clang 9, Visual Studio 2017
Actualmente acabo de hacer un máximo de 16 argumentos, pero si necesita más (¿de verdad ahora? Se está volviendo tonto ...) puede editar FUNC_CHOOSER y CHOOSE_FROM_ARG_COUNT, luego agregar algunas comas a NO_ARG_EXPANDER.
Consulte la excelente respuesta de Jason Deng para obtener más detalles sobre la implementación, pero solo pondré el código aquí:
#include<stdio.h>void realCreate(int x,int y){
printf("(%d, %d)\n", x, y);}// This part you put in some library header:#define FUNC_CHOOSER(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16,...) _f16
#define FUNC_RECOMPOSER(argsWithParentheses) FUNC_CHOOSER argsWithParentheses
#define CHOOSE_FROM_ARG_COUNT(F,...) FUNC_RECOMPOSER((__VA_ARGS__, \
F##_16, F##_15, F##_14, F##_13, F##_12, F##_11, F##_10, F##_9, F##_8,\
F##_7, F##_6, F##_5, F##_4, F##_3, F##_2, F##_1, ))#define NO_ARG_EXPANDER(FUNC),,,,,,,,,,,,,,,,FUNC ## _0#define MACRO_CHOOSER(FUNC,...) CHOOSE_FROM_ARG_COUNT(FUNC, NO_ARG_EXPANDER __VA_ARGS__ (FUNC))#define MULTI_MACRO(FUNC,...) MACRO_CHOOSER(FUNC, __VA_ARGS__)(__VA_ARGS__)// When you need to make a macro with default arguments, use this:#define create(...) MULTI_MACRO(CREATE, __VA_ARGS__)#define CREATE_0() CREATE_1(0)#define CREATE_1(x) CREATE_2(x,0)#define CREATE_2(x, y) \
do{ \
/* put whatever code you want in the last macro */ \
realCreate(x, y); \
}while(0)int main(){
create();
create(10);
create(20,20);//create(30, 30, 30); // Compilation errorreturn0;}
Ninguno de los ejemplos anteriores (de Derek Ledbetter, David Sorkovsky y Joe D) para contar argumentos con macros funcionó para mí usando Microsoft VCC 10. El __VA_ARGS__argumento siempre se considera como un solo argumento (tokenizándolo con ##o no), por lo que el cambio de argumento en el que se basan esos ejemplos no funciona.
Entonces, respuesta corta, como lo indicaron muchos otros anteriormente: no, no puede sobrecargar macros o usar argumentos opcionales en ellas.
Puede, pero solo en C99 o C ++ 11 (debido a que tiene __VA_ARGS__). VC2010 es C89 / C ++ 03 (con algunos bits de C ++ 11 comenzando a aparecer, pero todavía no).
No you can't
Respuestas:
He aquí una forma de hacerlo. Utiliza la lista de argumentos dos veces, primero para formar el nombre de la macro auxiliar y luego para pasar los argumentos a esa macro auxiliar. Utiliza un truco estándar para contar el número de argumentos de una macro.
Esto lo hace más fácil para quien llama a la macro, pero no para quien escribe.
fuente
PRINT_STRING_MACRO_CHOOSER
siquiera necesario? ¿Puedo reemplazarlo con su cuerpo interno directamente y llamar a todo esto con(__VA_ARGS__)
?Con gran respeto a Derek Ledbetter por su respuesta, y con disculpas por revivir una vieja pregunta.
Obtener una comprensión de lo que estaba haciendo y retomar en otro lugar la capacidad de preceder al
__VA_ARGS__
con##
me permitió encontrar una variación ...Para los no expertos como yo que se topan con la respuesta, pero no pueden ver cómo funciona, pasaré por el procesamiento real, comenzando con el siguiente código ...
Se vuelve ...
Que se convierte en el sexto argumento ...
PD: Elimine #define para XXX_0 para obtener un error de compilación [es decir, si no se permite una opción sin argumentos].
PPS: ¡Sería bueno que las situaciones inválidas (por ejemplo: 5) fueran algo que ofreciera un error de compilación más claro al programador!
PPPS: No soy un experto, así que estoy muy feliz de escuchar comentarios (buenos, malos u otros).
fuente
XXX_X(,##__VA_ARGS__,` ...
XXX_X (, XXX_4 (), XXX_3 (), XXX_2 (), XXX_1 (), XXX_0 ()); `Las macros de C ++ no han cambiado de C. Dado que C no tenía sobrecarga ni argumentos predeterminados para las funciones, ciertamente no los tenía para las macros. Entonces, para responder a su pregunta: no, esas funciones no existen para las macros. Su única opción es definir múltiples macros con diferentes nombres (o no usar macros en absoluto).
Como nota al margen: en C ++ generalmente se considera una buena práctica alejarse de las macros tanto como sea posible. Si necesita funciones como esta, es muy probable que esté abusando de las macros.
fuente
__FILE__
y__LINE__
y tal ...Con el mayor respeto a Derek Ledbetter , David Sorkovsky , Syphorlate por sus respuestas, junto con el ingenioso método para detectar macro argumentos vacíos de Jens Gustedt en
https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
finalmente salgo con algo que incorpora todos los trucos, para que la solución
, ##__VA_ARGS__
para GCC / CLANG, y deglución implícita por##__VA_ARGS__
para MSVC). Así que siéntase libre de pasar lo que falta--std=c99
a su compilador si lo desea =)Funciona razonablemente multiplataforma , al menos probado para
Para los perezosos, simplemente salte al último de esta publicación para copiar la fuente. A continuación se muestra la explicación detallada, que con suerte ayuda e inspira a todas las personas que buscan
__VA_ARGS__
soluciones generales como yo. =)Así es como funciona. En primer lugar definir la "función" visible para el usuario sobrecargado, lo nombré
create
, y la definición de función real relacionadarealCreate
, y las definiciones de macro con diferente número de argumentosCREATE_2
,CREATE_1
,CREATE_0
, como se muestra a continuación:En
MACRO_CHOOSER(__VA_ARGS__)
última instancia, la parte se resuelve en los nombres de las definiciones de macro y la segunda(__VA_ARGS__)
parte comprende sus listas de parámetros. Entonces, la llamada de un usuario a secreate(10)
resuelve enCREATE_1(10)
, laCREATE_1
parte proviene deMACRO_CHOOSER(__VA_ARGS__)
y la(10)
parte proviene del segundo(__VA_ARGS__)
.El
MACRO_CHOOSER
utiliza el truco de que, si__VA_ARGS__
está vacía, la siguiente expresión se concatena en una llamada a la macro válida por el preprocesador:Ingeniosamente, podemos definir esta macro llamada resultante como
Tenga en cuenta las dos comas, se explicarán pronto. La siguiente macro útil es
entonces las llamadas de
en realidad se expanden a
Como sugiere el nombre de la macro, más adelante contaremos el número de argumentos. Aquí viene otro truco: el preprocesador solo realiza un simple reemplazo de texto. Infiere el número de argumentos de una llamada de macro simplemente del número de comas que ve entre paréntesis. Los "argumentos" reales separados por comas no necesitan tener una sintaxis válida. Pueden ser cualquier texto. Es decir, en el ejemplo anterior,
NO_ARG_EXPANDER 10 ()
se cuenta como 1 argumento para la llamada intermedia.NO_ARG_EXPANDER 20
y20 ()
se cuentan como 2 argumentos para la última llamada respectivamente.Si usamos las siguientes macros auxiliares para expandirlas aún más
El seguimiento
,
posteriorCREATE_1
es una solución alternativa para GCC / CLANG, suprimiendo un error (falso positivo) que dice esoISO C99 requires rest arguments to be used
cuando se pasa-pedantic
a su compilador. ElFUNC_RECOMPOSER
es un trabajo en torno a MSVC, o que no se puede contar el número de argumentos (es decir, comas) dentro del paréntesis de las llamadas macro correctamente. Los resultados se resuelven además aComo el ojo de águila que puede haber visto, el último único paso que necesitamos es emplear un truco de conteo de argumentos estándar para finalmente elegir los nombres de la versión de macro deseados:
que resuelve los resultados a
y ciertamente nos da las llamadas de función reales deseadas:
Poniendo todo junto, con una reordenación de las declaraciones para una mejor legibilidad, la fuente completa del ejemplo de 2 argumentos está aquí:
Aunque complicado, feo, agobiante al desarrollador de API, llega una solución para sobrecargar y configurar parámetros opcionales de funciones C / C ++ para nosotros los locos. El uso de las API sobrecargadas resultantes se vuelve muy agradable y agradable. =)
Si existe alguna posible simplificación adicional de este enfoque, hágamelo saber en
https://github.com/jason-deng/C99FunctionOverload
¡De nuevo un agradecimiento especial a todas las personas brillantes que me inspiraron y me llevaron a lograr este trabajo! =)
fuente
Para cualquiera que busque dolorosamente alguna solución VA_NARGS que funcione con Visual C ++. La siguiente macro funcionó para mí perfectamente (¡también con cero parámetros!) En visual c ++ express 2010:
Si desea una macro con parámetros opcionales, puede hacer:
Eso funcionó para mí también en vc. Pero no funciona para cero parámetros.
fuente
unresolved external symbol _bool referenced in function _main
gcc
/g++
admite macros varargs, pero no creo que esto sea estándar, así que úselo bajo su propio riesgo.fuente
DESCARGO DE RESPONSABILIDAD: Mayormente inofensivo.
fuente
:%s/MY_MACRO_/THINK_/g
:)i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
Eso no es realmente para lo que está diseñado el preprocesador.
Dicho esto, si desea entrar en el área de la programación de macros que desafía seriamente con un mínimo de legibilidad, debería echar un vistazo a la biblioteca del preprocesador Boost . Después de todo, ¡no sería C ++ si no hubiera tres niveles de programación completamente compatibles con Turing (preprocesador, metaprogramación de plantillas y nivel básico C ++)!
fuente
En el momento de la llamada, sabe cuántos argumentos va a pasar, por lo que realmente no hay necesidad de sobrecargar.
fuente
Versión más concisa del código de Derek Ledbetter:
fuente
Como gran fanático de los horribles monstruos macro, quería ampliar la respuesta de Jason Deng y hacerla realmente utilizable. (Para bien o para mal). El original no es muy agradable de usar porque necesita modificar la gran sopa de letras cada vez que desea crear una nueva macro y es aún peor si necesita una cantidad diferente de argumentos.
Así que hice una versión con estas características:
Actualmente acabo de hacer un máximo de 16 argumentos, pero si necesita más (¿de verdad ahora? Se está volviendo tonto ...) puede editar FUNC_CHOOSER y CHOOSE_FROM_ARG_COUNT, luego agregar algunas comas a NO_ARG_EXPANDER.
Consulte la excelente respuesta de Jason Deng para obtener más detalles sobre la implementación, pero solo pondré el código aquí:
fuente
Puede utilizar
BOOST_PP_OVERLOAD
desde unboost
biblioteca.Ejemplo del documento oficial de boost :
fuente
Dependiendo de lo que necesite, puede hacerlo con var args con macros. Ahora, parámetros opcionales o sobrecarga de macros, no existe tal cosa.
fuente
Ninguno de los ejemplos anteriores (de Derek Ledbetter, David Sorkovsky y Joe D) para contar argumentos con macros funcionó para mí usando Microsoft VCC 10. El
__VA_ARGS__
argumento siempre se considera como un solo argumento (tokenizándolo con##
o no), por lo que el cambio de argumento en el que se basan esos ejemplos no funciona.Entonces, respuesta corta, como lo indicaron muchos otros anteriormente: no, no puede sobrecargar macros o usar argumentos opcionales en ellas.
fuente