2013-02-19 57 views
0

我試圖以一種可重複的方式多次調用這個函數。根據參數的數量生成多個宏調用

template<class T> 
void METADATA_METHODS_IMPL(std::string& metadata, const T &value, const std::string &key) 
{ 
    metadata += boost::format("%1%:%2%") % key % value(); 
} 

我寫了下面的宏:

#define METADATA_METHODS_IMPL_1(md, v1)\ 
    METADATA_METHODS_IMPL(md, v1, #v1); 

#define METADATA_METHODS_IMPL_2(md, v1, v2)\ 
    METADATA_METHODS_IMPL_1(md, v1)\ 
    METADATA_METHODS_IMPL_1(md, v2) 

#define METADATA_METHODS_IMPL_3(md, v1, v2, v3)\ 
    METADATA_METHODS_IMPL_2(md, v1, v2)\ 
    METADATA_METHODS_IMPL_1(md, v3) 

等等...

我需要調用METADATA_METHODS_IMPL_N其中N__VA_ARGS__

#define METADATA_METHODS(...)\ 
std::string METADATA_METHODS_IMPL_FUNC()\ 
{\ 
    std::string metadata;\ 
    BOOST_PP_OVERLOAD(METADATA_METHODS_IMPL_,__VA_ARGS__)(metadata, __VA_ARGS__)\ 
    return metadata;\ 
} 
多個參數

上面的代碼(與BOOST_PP_OVERLOAD)給我不合適結果:

class X 
{ 
    std::string F1(); 
    std::string F2(); 
    std::string F3(); 

    METADATA_METHODS(F1, F2, F3); 
}; 

這導致

std::string METADATA_METHODS_IMPL_FUNC() 
{ 
    std::string metadata; 
    METADATA_METHODS_IMPL(metadata, F1, F2, F3, "F1", "F2", "F3"); 
    METADATA_METHODS_IMPL(metadata, , ""); 
    METADATA_METHODS_IMPL(metadata, , ""); 
    return metadata; 
}; 

我想是這樣的:

std::string METADATA_METHODS_IMPL_FUNC() 
{ 
    std::string metadata; 
    METADATA_METHODS_IMPL(metadata, F1, "F1"); 
    METADATA_METHODS_IMPL(metadata, F2, "F2"); 
    METADATA_METHODS_IMPL(metadata, F3, "F3"); 
    return metadata; 
}; 
  • 有誰知道如何達到預期的效果?
  • 我可以使用Boost.preprocessor庫使用METADATA_METHODS_IMPL_1
+1

可能重複的[可變參數

#define MM() MM_CALL #define MM_NEXT(Macro,md,a,...) \ IS_DONE(a)( \ EAT \ , \ OBSTRUCT(MM)() \ ) \ (Macro,md,a,__VA_ARGS__) #define MM_CALL(Macro,md,a,...) \ Macro(md,a) \ MM_NEXT(Macro,md,__VA_ARGS__) #define MacroMap(Macro,md,...) EVAL(MM_CALL(Macro,md,__VA_ARGS__,DONE)) 

限定的實施相關的功能

#define METADATA_METHODS_IMPL_MACRO(md,a) \ METADATA_METHODS_IMPL(md, a, #a); #define METADATA_METHODS(md,...) \ MacroMap(METADATA_METHODS_IMPL_MACRO,md,__VA_ARGS__) \ return md 

此之後宏觀把戲](http:// stacko verflow.com/questions/5365440/variadic-macro-trick) – PlasmaHH 2013-02-19 15:11:32

+1

這裏的東西,可以使用的:http://stackoverflow.com/questions/2308243/macro-returning-the-number-of-arguments-it-is -given-in-c – StoryTeller 2013-02-19 15:13:51

+0

@PlasmaHH,我認爲這個話題在第二個問題得到解答之前是無法關閉的。不過,感謝您的幫助。一個下去,一個去:) – maverik 2013-02-19 15:17:34

回答

0

使用這些宏自動的生成METADATA_METHODS_IMPL_K一些K in [1 .. 10]我們可以使預處理器在保持重新掃描,並允許遞歸宏。

#define EVAL(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) 
#define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) 
#define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) 
#define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__))) 
#define EVAL0(...) __VA_ARGS__ 

我們可以定義一些幫助函數來構建概念。

#define CAT(a, ...) PRIMITIVE_CAT(a,__VA_ARGS__) 
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ 

#define EMPTY() 
#define EAT(...) 
#define IDENT(...) __VA_ARGS__ 
#define DEFER(id) id EMPTY() 
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)() 

#define I_TRUE(t,f) t 
#define I_FALSE(t,f) f 
#define I_IS_DONE(a,b,...) b 
#define TRUE_DONE() ~, I_TRUE 
#define IS_DONE(b) OBSTRUCT(I_IS_DONE)(CAT(TRUE_,b)(),I_FALSE) 

並建立這個宏映射函數,它攜帶第一個參數給每個。

METADATA_METHODS(metadata, F1, F2, F3); 

結果在此(添加一些格式後)::的

METADATA_METHODS_IMPL(metadata, F1, "F1"); 
METADATA_METHODS_IMPL(metadata, F2, "F2"); 
METADATA_METHODS_IMPL(metadata, F3, "F3"); 
return metadata;