2013-07-16 10 views
5

'possibile scrivere una macro preprocessore tali da dover trasformare un numero variabile di argomenti in chiamate di funzione successive, comeC Macro espansione in funzione più chiamate

MAP(f, 1, 2, 3, ..., n) 

in

f(1); f(2); f(3); ... f(n); 

Così lontano, ho seguito, che sembra funzionare:

#define MAP(f, t, ...) \ 
{\ 
    t __varlist[] = {__VA_ARGS__};\ 
    for(int i = 0; i < sizeof(__varlist)/sizeof(t); i++)\ 
     f(__varlist[i]);\ 
} 

Si noti che questa macro tak es un parametro di tipo in modo che possa essere un po 'più utile.

C'è un modo per farlo senza dichiarare un temporaneo? O non importa, perché il compilatore è così intelligente da capire tutto? Sono una specie di nuovo a C.

+1

Se non c'è modo di farlo in un solo passaggio avrete bisogno di più di pre-processore passa. http://en.wikipedia.org/wiki/M4_(computer_language) –

+0

@JohnSmith è ovviamente possibile se generi ancora più confusione ...;) – Gleno

+0

Non è ovvio per me dato che non so tutto del pre processore, quindi il qualificatore if. Sembra che entrambi i modi facciano un pasticcio ragionevole: P –

risposta

1

In gcc, è possibile evitare il tipo con typeof:

#define MAP(f, a1, ...) \ 
{\ 
    typeof(a1) __varlist[] = {a1, __VA_ARGS__};\ 
    for(int i = 0; i < sizeof(__varlist)/sizeof(t); i++)\ 
     f(__varlist[i]);\ 
} 

Farlo senza una temporanea, vale a dire in realtà la costruzione di N chiamate se ci sono parametri N, è possibile , ma piuttosto complicato, e sarà limitato a un massimo (per supportare fino a N, dovrai definire N macro).
Per fare ciò, avrai bisogno di una macro che conti i suoi argomenti (cerca questo sito) e usa questo numero, oltre alla concatenazione, per scegliere una delle macro N (ad esempio MAP1(f, a), MAP2(f, a, b) e così via).

+0

Penso che questa sia la migliore soluzione al mio problema così com'è. Nota che ho anche rinominato la variabile di indicizzazione in '__idx' per evitare conflitti. Suppongo che questo è ciò che dovresti fare. – Gleno

2

utilizzare boost.

nota: limite di dimensione 256. BOOST_PP_LIMIT_SEQ

#include <stdio.h> 
#include <boost/preprocessor/seq/for_each.hpp> 
#include <boost/preprocessor/tuple/size.hpp> 
#include <boost/preprocessor/tuple/to_seq.hpp> 

#define PROC(r, f, elem) f(elem); 
//#define MAP(f, ...) BOOST_PP_SEQ_FOR_EACH(PROC, f, BOOST_PP_TUPLE_TO_SEQ(BOOST_PP_TUPLE_SIZE((__VA_ARGS__)),(__VA_ARGS__))) 
#define MAP(f, ...) BOOST_PP_SEQ_FOR_EACH(PROC, f, BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) 

void f(int data){ 
    printf("%d\n", data); 
} 

int main(){ 

    MAP(f, 1, 2, 3); 
    return 0; 
} 
+0

Grazie per un fantastico suggerimento. Comunque è troppa magia per quello che vale. Penso che sia meglio per me provare a mantenere macro e dipendenze il più semplice possibile. – Gleno