2014-04-01 26 views
2

我想實現一個新的最大/最小微距,這可能需要兩個以上的參數,例如:我們可以實現最大或最小微距,可以採取可變參數(兩個以上參數)

#define max(...) ... 

然後,我可以用它像這樣:

max(p0, p1, p2, p3) 
max(2, 4, 100) 
max(1,2,3,4,5,6,7) -> 7 

如果這個宏可以幫助我們實現一個宏?

#define PP_EXPAND(X) X 
#define PP_ARG_COUNT(...) PP_EXPAND(PP_ARG_POPER(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) 
#define PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N 

#define PP_ARG_AT(Index, ...) PP_ARG_AT_##Index(__VA_ARGS__) 
#define PP_ARG_AT_0(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, __VA_ARGS__)) 
#define PP_ARG_AT_1(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, __VA_ARGS__)) 
#define PP_ARG_AT_2(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, __VA_ARGS__)) 
#define PP_ARG_AT_3(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, __VA_ARGS__)) 
#define PP_ARG_AT_4(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, __VA_ARGS__)) 
#define PP_ARG_AT_5(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, __VA_ARGS__)) 
#define PP_ARG_AT_6(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, __VA_ARGS__)) 
#define PP_ARG_AT_7(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, __VA_ARGS__)) 
#define PP_ARG_AT_8(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, __VA_ARGS__)) 
#define PP_ARG_AT_9(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, __VA_ARGS__)) 
#define PP_ARG_AT_10(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, _6, __VA_ARGS__)) 
#define PP_ARG_AT_11(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, __VA_ARGS__)) 
#define PP_ARG_AT_12(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, __VA_ARGS__)) 
#define PP_ARG_AT_13(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, __VA_ARGS__)) 
#define PP_ARG_AT_14(...) PP_EXPAND(PP_ARG_POPER(_1, _2, __VA_ARGS__)) 
#define PP_ARG_AT_15(...) PP_EXPAND(PP_ARG_POPER(_1, __VA_ARGS__)) 
#define PP_ARG_AT_16(...) PP_EXPAND(PP_ARG_POPER(__VA_ARGS__)) 
+0

您好,我不會用這個代碼,我問這個問題,因爲我想學習預處理的這種技術accoss這個稱號,非常感謝 – Hikari

+0

這是C還是C++?選一個。在C++中,可以使用更強大的技術來代替宏。 – immibis

+1

http://www.boost.org/doc/libs/1_55_0/libs/preprocessor/doc/ref/max_d.html – BLUEPIXY

回答

3

在C++ 11,std::max作品與initializer_list,所以您可以使用

std::max({40, 31, 42, 13, 4, 25, 16, 27}); 

而且如果你真的想MAX(p1, p2, p3)語法,你可以這樣做:

#define MAX(...) std::max({__VA_ARGS__}) 
1

有C++ STL算法做相同的:

max_element

min_element

使用這些替代寫宏來實現這一目標開始:

int arr[] = {1,2,3,4,5}; 
int* min = std::min_element(arr, arr+5); 
int* max = std::max_element(arr,arr+5); 
std::cout<<"min:"<<*min<<"max:"<<*max<<std::endl; 
+0

嗨,我不會使用這段代碼,我問了這個問題,因爲我想研究這個技術的預處理器,非常感謝...... – Hikari

+0

@Hikari:幾乎沒有必要在純C++中編寫MACRO。這些STL算法與MACRO一樣高效(幾乎)。您也可以使用內聯概念來實現MACRO類型的行爲。所以你應該學習這些概念,而不是MACRO ..選擇是你的:) –

+0

@tmp它可能仍然是一個有趣的學習練習。我們不能讀Hikari的想法。 – immibis

1

使用Boost.Preprocessor,你可以這樣實現它:

#define MAX_FOLD(s, state, elem) BOOST_PP_MAX(state, elem) 
#define MAX(...) BOOST_PP_SEQ_FOLD_LEFT(MAX_FOLD, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) 

由於預處理程序在擴展期間不直接支持比較,這是很多工作t o從頭開始實施這一切。使用技巧here,你可以實現一個計數器和一個while循環結構。通過這種方式,您可以實施減法,這將允許您實施小於(或大於),MAX所需的小於(或大於)。然後與另一個while你可以摺疊varidiac參數。

最後,在預處理器中做所有這些工作都有一些限制。預處理程序不完全完成。因此,在升壓示例中,您將被限制爲0到256之間的值(這完全是升壓限制,如果您自己動手,則可以提高該限制)。根據您想達到什麼目的,它可能是最好寫一個最大功能varidiac:

template<class T, class U> 
T max(T x, T y) 
{ 
    return x > y ? x : y; 
} 

template<class... Ts> 
T max(T x, Ts... xs) 
{ 
    return max(x, max(xs...)); 
} 
相關問題