我想实现一个新的max/min宏,它可以接受两个以上的参数,例如:
#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__))发布于 2014-07-10 16:43:37
在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__})发布于 2019-07-23 15:07:24
您的问题包含了一半的答案-您可以使用min宏中显示的技术构建带有变量参数号的PP_ARG_COUNT /max宏(与原始代码一样,参数的数量将有限制,但您可以选择)。
下面是示例代码(最多4个参数):
#include <stdio.h>
#define __START(op, A, B, C, D, N, ...) __ARGS_##N(op, A, B, C, D)
#define __ARGS_1(op, A, B, C, D) A
#define __ARGS_2(op, A, B, C, D) __##op(A, B)
#define __ARGS_3(op, A, B, C, D) __##op(A, __##op(B, C))
#define __ARGS_4(op, A, B, C, D) __##op(__##op(A, B), __##op(C, D))
#define __MIN(A, B) ((A) < (B) ? (A) : (B))
#define __MAX(A, B) ((A) > (B) ? (A) : (B))
#define min(...) __START(MIN, __VA_ARGS__, 4, 3, 2, 1)
#define max(...) __START(MAX, __VA_ARGS__, 4, 3, 2, 1)
int main(void)
{
printf("min(1) -> %d\n\n", min(1));
printf("min(1.5, 2) -> %lf\n", min(1.5,2));
printf("min(3, 2, 1.5) -> %lf\n", min(3,2,1.5));
printf("min(1, 2, 3, 4) -> %d\n", min(1,2,3,4));
printf("min(2, 3, 4, 1) -> %d\n\n", min(2,3,4,1));
printf("max(2.5, 2.0) -> %lf\n", max(2.5, 2.0));
printf("max(3, 2, 3.5) -> %lf\n", max(3, 2, 3.5));
printf("max(1, 2, 3, 4) -> %d\n", max(1, 2, 3, 4));
printf("max(2, 3, 4, 1) -> %d\n", max(2, 3, 4, 1));
return 0;
}如果您编译并运行该程序,您将得到以下输出:
min(1) -> 1
min(1.5, 2) -> 1.500000
min(3, 2, 1.5) -> 1.500000
min(1, 2, 3, 4) -> 1
min(2, 3, 4, 1) -> 1
max(2.5, 2.0) -> 2.500000
max(3, 2, 3.5) -> 3.500000
max(1, 2, 3, 4) -> 4
max(2, 3, 4, 1) -> 4它是如何工作的。__START宏接受以下参数:
op -宏名(前面没有双下划线),它只使用两个参数执行必要的操作A、B、C、D -这些参数将接收min/max的参数,如果min/max参数的数量小于最大值(在本示例代码中为4个),则可能会收到一些虚拟参数。N - min/max参数的数量。... -其他一些愚蠢的论点。__START将根据参数号展开为__ARGS_1..__ARGS_4之一。通过添加调用4, 3, 2, 1宏的__START参数获得参数号:
#define min(...) __START(MIN, __VA_ARGS__, 4, 3, 2, 1)因此,如果您调用例如min(1.5, 2.5, 3.5),它将扩展到(我在注释中添加了参数名称):
__START(/*op=*/ MIN, /*A=*/ 1.5, /*B=*/ 2.5, /*C=*/ 3.5, /*D=*/ 4, /*N=*/ 3, 2, 1)然后,__START将扩展到__ARGS_3,下面的扩展非常简单。现在我们可以清楚地看到,参数数是如何“计算”的,以及它是如何工作的。您可以使用其他功能轻松地实现相同的宏,并增加参数的最大数量,例如sum。
#define __SUM(A, B) ((A)+(B))
#define sum(...) __START(SUM, __VA_ARGS__, 4, 3, 2, 1)认为它不像min/max那样有用。
如果使用VisualC++,则需要添加一些变通方法(如第一篇文章中的PP_EXPAND ),以克服VC++预处理器错误详情见。我用GCC,它不需要一个。
发布于 2014-04-01 01:45:57
有C++ STL算法来做同样的事情:
元素。 元素
开始使用这些,而不是编写宏来实现这一点:
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;https://stackoverflow.com/questions/22775312
复制相似问题