2017-06-18 89 views
3

實例化模板函數和類與看似標準wxyz演示工作,假設我有以下宏試圖將轉換爲一個「迭代」預處理宏與升壓預處理

#define INSTANTIATE_FUNC(rtype, func_name, ...) \ 
    template rtype func_name<w> (__VA_ARGS__); \ 
    template rtype func_name<x> (__VA_ARGS__); \ 
    template rtype func_name<y> (__VA_ARGS__); \ 
    template rtype func_name<z> (__VA_ARGS__); 

對於完整性,假設我們正在試圖實例以下

struct w { static constexpr int data = 0; }; 
struct x { static constexpr int data = 1; }; 
struct y { static constexpr int data = 2; }; 
struct z { static constexpr int data = 3; }; 

template <class Data> 
void printData(const std::string &prefix) { 
    std::cout << prefix << Data::data << std::endl; 
} 

INSTANTIATE_FUNC(void, printData, const std::string &prefix) 

我爲了方便做了一個minimal gist with a build system這樣,如果你有興趣嘗試你不必重新創建所有的東西:)

我不能完全弄清楚如何解決這個問題。只有功能(但沒有用)刺

#include <boost/preprocessor/list/for_each.hpp> 

#define LIST (w, (x, (y, (z, BOOST_PP_NIL)))) 
#define MACRO(r, data, elem) template void data <elem> (const std::string &prefix); 

#define INSTANTIATE_FUNC(rtype, func_name, ...) \ 
    BOOST_PP_LIST_FOR_EACH(MACRO, func_name, LIST) 

這是工程,但顯然是不夠的。

  1. 爲什麼這不是與序列工作?

    #include <boost/preprocessor/seq/for_each.hpp> 
    // this does work, my code included the wrong header 
    // on what I was testing with (seq/for_each_i.hpp) 
    
    #define SEQ (x)(y)(z)(w) 
    #define INSTANTIATE_FUNC(rtype, func_name, ...) \ 
        BOOST_PP_SEQ_FOR_EACH(MACRO, func_name, SEQ) 
    
  2. 我應該如何接近建設template rtype func_name < {w,x,y,z} > {args,in,__VA_ARGS__}?我嘗試了很多不同的事情,但問題似乎無法如只提取w,然後通過__VA_ARGS__循環,然後繼續。我一直在努力讓BOOST_PP_LIST_FOR_EACH_R工作。這至少是正確的事情嗎?

  3. 作爲一個健全檢查,你不能在一個宏的權利內定義一個宏嗎?東西的

    #define INSTANTIATE_FUNC(rtype, func_name, ...) \ 
        #define MACRO_##func_name(r, data, elem) data <elem> (__VA_ARGS__); \ 
        BOOST_PP_LIST_FOR_EACH(MACRO_##func_name, func_name, LIST) 
    

精神,我最終走向有利的LIST/SEQ可選的擴展的目標而努力(SEQ似乎容易達到這一目的),如果這意味着什麼。感謝您的任何建議/資源。

回答

1

您的問題似乎是,您需要將若干條數據傳送到MACROBOOST_PP_(LIST|SEQ)_FOR_EACH,並且只有一個「插槽」可供您使用。你似乎缺少的東西是,你可以將這些片段分組在一個元組中,然後使用BOOST_PP_TUPLE_ELEM訪問MACRO中的不同元素。像這樣的東西可以工作:

//These are not required, just to help with readability 
#define MACRO_GET_RETURN_TYPE(TUPLE) BOOST_PP_TUPLE_ELEM(3,0,TUPLE) 
#define MACRO_GET_FUNC_NAME(TUPLE) BOOST_PP_TUPLE_ELEM(3,1,TUPLE) 
#define MACRO_GET_ARGS_SEQ(TUPLE) BOOST_PP_TUPLE_ELEM(3,2,TUPLE) 


#define MACRO(_, DATA, ELEM) template MACRO_GET_RETURN_TYPE(DATA) MACRO_GET_FUNC_NAME(DATA) <ELEM> (BOOST_PP_SEQ_ENUM(MACRO_GET_ARGS_SEQ(DATA))); 

// with boost seq 
#define SEQ (x)(y)(z)(w) 

#define INSTANTIATE_FUNC(rtype, func_name, ...) \ 
    BOOST_PP_SEQ_FOR_EACH(MACRO, (rtype,func_name,BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), SEQ) 

Live on Wandbox

PS:不,你不能在宏內定義一個宏,你張貼在這裏的代碼不工作序列中,一個在你的要點做不是由於使用錯誤的標題。

+0

哇!是的,我完全沒有意識到我可以「調整」我的宏。這是純粹的魔法,是一個徹頭徹尾的遊戲改變者。有了這個能力,我可以比我原先想象的更進一步。 Muahahaha。我知道這一定是可能的。感謝您向我展示如何:) P.S.是的,後面的'i'對序列* faceslap *有很大的影響。作爲額外的好處,'wandbox'比'gist'更好... – sjm324