2010-08-06 120 views
4

我想要做一些宏「重載」,以便MACRO(東西),得到不同於MACRO(東西,其他)的擴展。C預處理器,宏「重載」

使用一個片段,我從here了(我不知道這是否是100%便攜式),並從升壓PP圖書館的一些功能,我能使其工作:d現在

//THESE TWO COUNT THE NUMBER OF ARGUMENTS 
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N 
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1) 

//THIS ONE RETURNS THE PARAMETER AT POSITION _i FROM A LIST OF __VA_ARGS__ 
#define VA_ARG(_i, ...) BOOST_PP_ARRAY_ELEM(_i, (VA_NARGS(__VA_ARGS__), (__VA_ARGS__))) 

//AND THIS ONE IS THE 'OVERLOADED' MACRO ;) 
#define TEST(...) BOOST_PP_IF(BOOST_PP_EQUAL(1, VA_NARGS(__VA_ARGS__)), function_A(VA_ARG(0, __VA_ARGS__)), \ //1 parameter 
        BOOST_PP_IF(BOOST_PP_EQUAL(2, VA_NARGS(__VA_ARGS__)), function_B(VA_ARG(0, __VA_ARGS__) + VA_ARG(1, __VA_ARGS__)), \ //2 parameters 
        BOOST_PP_IF(BOOST_PP_EQUAL(3, VA_NARGS(__VA_ARGS__)), function_C(VA_ARG(1, __VA_ARGS__) + VA_ARG(2, __VA_ARGS__)), BOOST_PP_EMPTY())) // 3 parameters and so on ... 

So  TEST(a) = function_A(a) 
     TEST(a, b) = function_B(a + b) 
    TEST(a, b, c) = function_C(b + c) 

我「M仍下落不明另外兩個是我想要做的事情:

  1. (這一次我真的不關心,如果我從來沒有解決這個問題)我相信,一個宏可以寫成佔用時的數'variants'和它的記者'輸出'產生一個類似於上面的代碼。像TEMPLATE(3,function_A(...),function_B(...),function_C(...))來產生上面的例子。

  2. 當沒有參數調用TEST()時會發生什麼?那麼,VA_NARGS擴展爲1.但第一個參數是「」(沒有)。我試圖找到一種方法來檢測__VA_ARGS__中的「零」參數,或者區分「空」參數和真實參數,以便擴展「超載」功能以對此情況作出反應。有任何想法嗎?

+0

如果可以的話投票提問! :) – almosnow 2010-08-06 02:23:20

+2

Boost - > C++ - >如果您已經在使用C++,請不要混淆預處理器,請使用普通函數(如果您希望內聯)。 C預處理器故意啞巴,以免人們濫用它。 – Dummy00001 2010-08-06 04:21:37

+0

這是用於C還是C++?還要注意,使用可變參數和宏是不可移植的。 – 2010-08-06 06:01:25

回答

4

先回答你的問題2。是的,使用可變宏可以檢測一個空的參數列表。解釋有點冗長,我寫了它here。將此方法與您正在使用的boost宏組合起來應該相對容易。

對於你的問題1,是的,這也是可能的。 Boost的一些迭代宏已經接近這個,我想,但他們看起來有點可怕。如果我理解正確,你必須使用像嵌套列表(a, (b, (c,d))),不太方便。

(我寫了一組宏可在此更直接地實現, 可惜包還沒有準備好發佈。聯繫我私人如果你是真的感興趣。)

編輯:P99包在同時發佈,幷包含了很多東西在宏「重載」和類型通用宏。

+1

Boost迭代器宏有幾種不同的類型序列:列出'(a(b(c,d)))',元組'(a,b,c)'(長度必須是已知的)並列出'(a)(b)(c)'。後者對我來說是最容易處理的。 – KitsuneYMG 2010-08-06 17:59:03

+0

延斯,你搖滾,工作完美無缺:)。非常感謝! – almosnow 2010-08-06 22:26:09