2013-07-16 18 views
5

Czy to możliwe, aby napisać makro preprocesora takie, które przekształcić zmienną liczbę argumentów do kolejnych wywołań funkcji, takich jakC Makro ekspansja na stwardnienie wywołań funkcji

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

do

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

So daleko, mam następujące, które wydaje się działać:

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

Pamiętaj, że to makro es parametr typu, aby był bardziej przydatny.

Czy można to zrobić bez zadeklarowania tymczasowego? Czy to nie ma znaczenia, ponieważ kompilator jest tak inteligentny, że wszystko odczytuje? Jestem trochę nowych do C

+1

Jeśli nie ma sposobu, aby to zrobić w jednym przejściu musisz stwardnienie pre-procesor przechodzi. http://pl.wikipedia.org/wiki/M4_(komputer_language) –

+0

@JohnSmith jest to oczywiście możliwe, jeśli wygenerujesz więcej bałaganu ...;) – Gleno

+0

Nie jest dla mnie oczywiste, ponieważ nie wiem wszystkiego o procesor, a więc kwalifikator if. Wygląda na to, że oba sposoby są rozsądne: P –

Odpowiedz

1

W gcc, można uniknąć typ z typeof:

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

Robi to bez tymczasowe, czyli naprawdę buduje N połączeń Jeśli istnieją parametry N, możliwe jest , ale raczej skomplikowane i będzie ograniczone do pewnej maksymalnej wartości (aby obsłużyć do N, będziesz musiał zdefiniować makra N).
Aby to zrobić, potrzebujesz makra, które zlicza jego argumenty (przeszukuj tę witrynę) i użyj tego numeru, a także konkatenacji, aby wybrać jedno z N makr (np. MAP1(f, a), MAP2(f, a, b) i tak dalej).

+0

Myślę, że jest to najlepsze rozwiązanie mojego problemu w obecnej formie. Zauważ, że zmieniłem nazwę zmiennej indeksującej na '__idx', aby uniknąć konfliktów. Zakładam, że to właśnie powinieneś zrobić. – Gleno

2

użyj doładowania.

uwaga: wielkość graniczna 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

Dzięki za fajną propozycję. Jednak jest zbyt dużo magii, aby to, co jest warte. Myślę, że najlepiej będzie, jeśli spróbuję zachować makra i zależności tak proste, jak to tylko możliwe. – Gleno