2013-07-16 13 views
5

是否有可能寫一個預處理宏使得將改變的可變數量的參數爲連續的函數調用,如C近拍膨脹成多個函數調用

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

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

所以遠,我有以下,這似乎工作:

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

請注意,這個宏tak es是一個類型參數,以便它可以更有用。

有沒有辦法做到這一點沒有申報臨時?或者沒有關係,因爲編譯器非常聰明,能夠計算出所有內容?我有點新C.

+1

如果沒有辦法做到這一點的一個通行證就需要多個預處理器傳遞。 http://en.wikipedia.org/wiki/M4_(computer_language) –

+0

@JohnSmith如果你產生更多的混亂,這顯然是可能的...;) – Gleno

+0

這對我來說並不明顯,因爲我不知道關於預定義的一切,處理器,因此如果限定符。看起來兩種方式都會造成合理的混亂:P –

回答

1

在GCC,可以避開與類型typeof

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

做它沒有一個臨時的,即真正建立N個已如果有N個參數,可以,但相當複雜,並且將被限制在某個最大值(爲了支持N,你需要定義N個宏)。
爲此,需要一個宏來計算它的參數(搜索此站點),並使用此數字和串聯來選擇N個宏中的一個(例如MAP1(f, a),MAP2(f, a, b)等)。

+0

我認爲這是解決我的問題的最佳解決方案。請注意,我也將索引變量重命名爲「__idx」以避免衝突。我假設這是你應該做的。 – Gleno

2

使用提升。

注:極限尺寸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

謝謝你的建議。然而它對於它的價值來說太過神奇了。我認爲儘可能簡單地嘗試並保持宏和依賴關係是最好的。 – Gleno