宏来替换嵌套的for循环 [英] Macro to replace nested for loops

查看:94
本文介绍了宏来替换嵌套的for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现此宏 #define TIMES(x)for(int i1 = 0; i1 非常实用,可以缩短代码文本.但是,当我有嵌套循环时,我也不知道如何编写这样的宏,甚至我也不知道是否可能.这个想法如下.可以编写这段代码

I found this macro #define TIMES(x) for(int i1=0;i1<x;i1++)very pratical to shorten the code text. But I do not know how to write such a macro when I have nested loops and even I do not know if it is possible. The idea is the following. Is it possible to write this code

for(int i1=0;i1<5;i1++)
    for(int i2=0;i2<3;i2++)
        for (int i3=0;i3<7;i3++)
        /* many nested `for` loops */
{
    /* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}

TIMES(5) TIMES(3) TIMES(7) ....
{
    /* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}

具有某种递归"宏,该宏可检测所有 TIMES ,并用 for 循环将其替换为i1,i2,i3,... i'n'循环计数器?

with a sort of "recursive" macro that detects all TIMES and replaces them by a forloop with i1, i2, i3, ... i'n' loop counters ?

推荐答案

我终于成功编写了此宏.在这篇非常好的文章中,我找到了大多数信息来做到这一点( http://jhnet.co.uk/articles/cpp_magic ).以下帖子(我们可以拥有递归宏吗? C ++预处理器__VA_ARGS__参数数量 ,,a>,可变参数宏技巧,...)也可以帮助我很多.该答案旨在回答问题.它没有解决宏和良好的编程习惯的问题.这是另一个主题.

这是代码

I finally succeed in writing this macro. I found most of the informations to do that in this very good article (http://jhnet.co.uk/articles/cpp_magic). The following posts (Can we have recursive macros?, Is there a way to use C++ preprocessor stringification on variadic macro arguments?, C++ preprocessor __VA_ARGS__ number of arguments, Variadic macro trick, ...) help me also a lot. This answer is intended to answer question. It does not address the question of macro and good programming pratices. It is another subject.

This is the code

#define SECOND(a, b, ...) b
#define IS_PROBE(...) SECOND(__VA_ARGS__, 0)
#define PROBE() ~, 1

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

#define NOT(x) IS_PROBE(CAT(_NOT_, x))
#define _NOT_0 PROBE()
#define BOOL(x) NOT(NOT(x))

#define IF_ELSE(condition) _IF_ELSE(BOOL(condition))
#define _IF_ELSE(condition) CAT(_IF_, condition)
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...)             _IF_0_ELSE
#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__

#define EMPTY()

#define EVAL(...) EVAL1024(__VA_ARGS__)
#define EVAL1024(...) EVAL512(EVAL512(__VA_ARGS__))
#define EVAL512(...) EVAL256(EVAL256(__VA_ARGS__))
#define EVAL256(...) EVAL128(EVAL128(__VA_ARGS__))
#define EVAL128(...) EVAL64(EVAL64(__VA_ARGS__))
#define EVAL64(...) EVAL32(EVAL32(__VA_ARGS__))
#define EVAL32(...) EVAL16(EVAL16(__VA_ARGS__))
#define EVAL16(...) EVAL8(EVAL8(__VA_ARGS__))
#define EVAL8(...) EVAL4(EVAL4(__VA_ARGS__))
#define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__))
#define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__))
#define EVAL1(...) __VA_ARGS__

#define DEFER1(m) m EMPTY()
#define DEFER2(m) m EMPTY EMPTY()()

#define FIRST(a, ...) a
#define HAS_ARGS(...) BOOL(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)())
#define _END_OF_ARGUMENTS_() 0

#define MAP(m, first, ...)           \
  m(first,__VA_ARGS__)                           \
  IF_ELSE(HAS_ARGS(__VA_ARGS__))(    \
    DEFER2(_MAP)()(m, __VA_ARGS__)   \
  )(                                 \
    /* Do nothing, just terminate */ \
  )
#define _MAP() MAP

#define PP_NARG(...) \
         PP_NARG_(,##__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
         PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
          z,_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
         _61,_62,_63,N,...) N
#define PP_RSEQ_N() \
         63,62,61,60,                   \
         59,58,57,56,55,54,53,52,51,50, \
         49,48,47,46,45,44,43,42,41,40, \
         39,38,37,36,35,34,33,32,31,30, \
         29,28,27,26,25,24,23,22,21,20, \
         19,18,17,16,15,14,13,12,11,10, \
         9,8,7,6,5,4,3,2,1,0

#define TIMES(...) EVAL(MAP(TIME2FOR,__VA_ARGS__))

#define TIME2FOR(x,...) \
        for(int CAT(i,PP_NARG(__VA_ARGS__))=0; \
            CAT(i,PP_NARG(__VA_ARGS__))<x; \
            CAT (i,PP_NARG(__VA_ARGS__))++)

main() {

int a[3][2][4];
TIMES(3,2,4) a[i2][i1][i0]=i2*100+i1*10+i0;
TIMES (3,2,4) printf("a[%d][%d][%d] : %d\n",i2,i1,i0,a[i2][i1][i0]);
TIMES (3,2,4) {/* whatever you want : loop indexes are ...,i2,i1,i0 */}
}

事实证明,这比我想象的要困难得多.

It turned out to be more difficult than I thought it would be.

这篇关于宏来替换嵌套的for循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆