2013-03-27 54 views
3

我有以下代碼:升壓預處理器不擴大

#include <boost/preprocessor.hpp> 

#define ARGS(r, data, elem) \ 
    BOOST_PP_COMMA_IF(BOOST_PP_SUB(r, 2)) \ 
    BOOST_PP_SEQ_ELEM(0, elem) BOOST_PP_SEQ_ELEM(1, elem) 

#define DEF_FUN(name, args) void name(BOOST_PP_SEQ_FOR_EACH(ARGS,,args)); 

#define DEF_FUNCTIONS_ELEM(r, data, elem) DEF_FUN(BOOST_PP_SEQ_ELEM(0, elem), BOOST_PP_SEQ_ELEM(1, elem)) 

#define DEF_FUNCTIONS(funSeqs) \ 
    BOOST_PP_SEQ_FOR_EACH(DEF_FUNCTIONS_ELEM,, funSeqs) 


DEF_FUNCTIONS_ELEM(2,, (fun0) (((int)(arg0)) ((char)(arg1)))) 

DEF_FUNCTIONS 
(
    ((fun0) (((int)(arg0)) ((char)(arg1)))) 
    ((fun1) (((char)(arg0)) ((long)(arg1)) ((short)(arg2)))) 
    ((fun3)()) 
) 

當我此進行預處理用鏘3.2或g ++ 4.6.3,我得到:

void fun0(int arg0 , char arg1); 

void fun0(BOOST_PP_SEQ_FOR_EACH(ARGS,,((int)(arg0)) ((char)(arg1)))); 
void fun1(BOOST_PP_SEQ_FOR_EACH(ARGS,,((char)(arg0)) ((long)(arg1)) ((short)(arg2)))); 
void fun3(BOOST_PP_SEQ_FOR_EACH(ARGS,,)); 

(I加入行分解爲清晰度)

問題是,爲什麼內部BOOST_PP_SEQ_FOR_EACH沒有擴展?

再次傳遞此輸出擴展了預期結果。

編輯:經過大量的搜索後,我讀了一個宏不會展開,如果它被調用兩次,我想這就是爲什麼。

編輯:我應該使用PP_SEQ_FOR_EACH_I,R不意味着被用作下標。

+0

現在我做蟒蛇最代碼生成,只有在宏小東西。 – chila 2015-04-15 15:17:37

回答

4

BOOST_PP_SEQ_FOR_EACH不是reentrant。在Boost.PP中只有幾個可重入的宏(BOOST_PP_FOR,BOOST_PP_WHILEBOOST_PP_REPEAT)。但是,您可以通過使用延遲表達式,這樣的解決辦法是:

#include <boost/preprocessor.hpp> 

#define EXPAND(...) __VA_ARGS__ 
#define EMPTY() 
#define DEFER(x) x EMPTY() 
// An indirection macro to avoid direct recursion 
#define BOOST_PP_SEQ_FOR_EACH_ID() BOOST_PP_SEQ_FOR_EACH 

#define ARGS(r, data, elem) \ 
    BOOST_PP_COMMA_IF(BOOST_PP_SUB(r, 2)) \ 
    BOOST_PP_SEQ_ELEM(0, elem) BOOST_PP_SEQ_ELEM(1, elem) 

// Defer BOOST_PP_SEQ_FOR_EACH_ID here 
#define DEF_FUN(name, args) void name(DEFER(BOOST_PP_SEQ_FOR_EACH_ID)()(ARGS,,args)); 

#define DEF_FUNCTIONS_ELEM(r, data, elem) DEF_FUN(BOOST_PP_SEQ_ELEM(0, elem), BOOST_PP_SEQ_ELEM(1, elem)) 

// Add EXPAND here to apply another scan to expand the deferred expression 
#define DEF_FUNCTIONS(funSeqs) \ 
    EXPAND(BOOST_PP_SEQ_FOR_EACH(DEF_FUNCTIONS_ELEM,, funSeqs)) 


DEF_FUNCTIONS 
(
    ((fun0) (((int)(arg0)) ((char)(arg1)))) 
    ((fun1) (((char)(arg0)) ((long)(arg1)) ((short)(arg2)))) 
    ((fun3)()) 
) 
+0

這個工作,太糟糕了,我們必須修改DEF_FUN使其成爲SEQ_FOR_EACH-able。有沒有辦法修改調用者而不是被調用者?太糟糕了,預處理器不會遞歸,至少有限次數。必須儘快橋接到mpl/fusion。 – chila 2013-03-28 16:08:23

1
#include <boost/preprocessor.hpp> 

#define ARGS(r, data, index, elem) \ 
    BOOST_PP_SEQ_ELEM(0, elem) BOOST_PP_SEQ_ELEM(1, elem) BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(index, BOOST_PP_DEC(data))) 

#define DEF_FUN(name, args) void name(BOOST_PP_SEQ_FOR_EACH_I(ARGS,BOOST_PP_SEQ_SIZE(args),args)); 

#define DEF_FUNCTIONS_ELEM(r, data, elem) DEF_FUN(BOOST_PP_SEQ_ELEM(0, elem), BOOST_PP_SEQ_ELEM(1, elem)) 

#define DEF_FUNCTIONS(funSeqs) \ 
    BOOST_PP_SEQ_FOR_EACH(DEF_FUNCTIONS_ELEM,, funSeqs) 


DEF_FUNCTIONS_ELEM(2,, (fun0) (((int)(arg0)) ((char)(arg1)))) 

DEF_FUNCTIONS 
(
    ((fun0) (((int)(arg0)) ((char)(arg1)))) 
    ((fun1) (((char)(arg0)) ((long)(arg1)) ((short)(arg2)))) 
    ((fun3)()) 
) 
+0

是的,這是一種可能性,我將主序列轉換爲PP_LIST,然後調用PP_LIST_FOR_EACH。但考慮到實際上應該使用PP_SEQ_FOR_EACH_I(請參閱我的編輯),我認爲應該使用更通用的解決方法。 – chila 2013-03-28 15:28:59