2014-04-01 24 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...)); 
} 
相关问题