Why won't this compile and how can it be implemented so that it does?

后端 未结 6 785
挽巷
挽巷 2020-12-21 12:30

Here is some C++ code I\'m playing around with:

#include 
#include 

#define IN ,
#define FOREACH(x,y) for(unsigned int i=0;i&l         


        
相关标签:
6条回答
  • 2020-12-21 12:44

    Expansion for IN doesn't happen early enough in your example, but you can pass the expanded version to another macro:

    #define FOREACH(x) DO_FOREACH(x)
    #define DO_FOREACH(x,y) for( ... ) ...
    
    0 讨论(0)
  • 2020-12-21 12:50

    The preprocessor doesn't expand the IN to a comma until after it reads the arguments to FOREACH.

    I'm pretty sure that the c++ preprocessor is one pass only, so you'll have to use:

    FOREACH(int item, ints)
        cout << item;
    ENDFOREACH
    
    0 讨论(0)
  • 2020-12-21 12:53
    #define IN ,
    #define XFOREACH(x,y) for(unsigned int i=0;i<y.size();i++) { x=y[i];
    #define FOREACH(x) XFOREACH(x)
    #define ENDFOREACH }
    

    As previous posters have noted, the preprocessor does not expand macros in the arglist before it splits it into argument. However, as long as the macro doesn't use # or ##, it expands macros in the args before substituting them into the macro body, so an extra indirection does the trick

    0 讨论(0)
  • 2020-12-21 13:00

    Others have already explained why it doesn't compile as is.

    In order to make it work you have to give that IN a chance to turn into a comma. For that you can introduce an extra level of "indirection" in your macro definition

    #define IN , 
    #define FOREACH_(x,y) for(unsigned int i=0;i<y.size();i++) { x=y[i]; 
    #define FOREACH(x) FOREACH_(x)
    #define ENDFOREACH } 
    

    In this case you'll have to use some substitute for comma (like your IN) and can no longer specify comma explicitly. I.e. now this

    FOREACH(int item IN ints) 
        cout << item; 
    ENDFOREACH 
    

    compiles fine, while

    FOREACH(int item, ints) 
        cout << item; 
    ENDFOREACH 
    

    does not.

    0 讨论(0)
  • 2020-12-21 13:02

    Check out BOOST_FOREACH - it does what you want

    http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html

    0 讨论(0)
  • 2020-12-21 13:03

    The compiler doesn't expand the IN macro before it reads the arguments to FOREACH. In fact, I think this is intentional (so that you can pass a comma to a macro).

    Unfortunately, you'll have to use FOREACH(int item, ints).

    You could also #define IN (make it nothing) and then use FOREACH(int item, IN ints), which is not quite as nice, but is acceptable.

    That said, you may just want to use STL or Boost for foreach, unless you specifically want to create your own.

    0 讨论(0)
提交回复
热议问题