代码之家  ›  专栏  ›  技术社区  ›  Nathan Osman

为什么不编译,如何实现?

  •  2
  • Nathan Osman  · 技术社区  · 14 年前

    下面是一些我正在玩的C++代码:

    #include <iostream>
    #include <vector>
    
    #define IN ,
    #define FOREACH(x,y) for(unsigned int i=0;i<y.size();i++) { x=y[i];
    #define ENDFOREACH }
    
    using namespace std;
    
    int main()
    {
        vector<int> ints;
        ints.push_back(3);
        ints.push_back(4);
        ints.push_back(5);
        ints.push_back(6);
    
        FOREACH(int item IN ints)
            cout << item;
        ENDFOREACH
    
        return 0;
    }
    

    但是,我得到一个错误:

    宏“foreach”需要2个参数,但只给定1个

    如果我更改 IN 逗号我怎样才能得到 代替逗号?

    更新: 对于那些感兴趣的人来说,这里是最终版本,如果我自己也这么说的话,这是非常好的。

    #include <iostream>
    #include <vector>
    
    #define in ,
    #define as ,
    #define FOREACH_(x,y,z) \
            y x; \
            if(z.size()) x = z[0]; \
            for(unsigned int i=0,item;i<z.size();i++,x=z[i])
    #define foreach(x) FOREACH_(x)
    
    using namespace std;
    
    int main()
    {
        vector<int> ints;
        ints.push_back(3);
        ints.push_back(4);
        ints.push_back(5);
        ints.push_back(6);
    
        foreach(item as int in ints)
        {
            cout << item << endl;
        }
    
        return 0;
    }
    
    6 回复  |  直到 8 年前
        1
  •  4
  •   AnT stands with Russia    14 年前

    其他人已经解释了为什么它不能按原样编译。

    为了成功,你必须 IN 变成逗号的机会。为此,您可以在宏定义中引入额外级别的“间接寻址”。

    #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 } 
    

    在这种情况下,您将不得不使用一些逗号的替代品(例如 )不能再显式指定逗号。也就是现在这个

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

    编译得很好,而

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

    没有。

        2
  •  3
  •   Zifre    14 年前

    编译器不会展开 IN 宏读取参数之前 FOREACH . 实际上,我认为这是有意的(这样您就可以将逗号传递给宏)。

    不幸的是,你必须使用 FOREACH(int item, ints) .

    你也可以 #define IN (什么都不做)然后使用 FOREACH(int item, IN ints) ,这不是很好,但可以接受。

    也就是说,您可能只想使用stl或boost for foreach,除非您特别想创建自己的。

        3
  •  1
  •   Georg Fritzsche    14 年前

    扩展 IN 在示例中发生的时间不够早,但可以将扩展版本传递给另一个宏:

    #define FOREACH(x) DO_FOREACH(x)
    #define DO_FOREACH(x,y) for( ... ) ...
    
        4
  •  1
  •   Chris Dodd    14 年前
    #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 }
    

    正如前面的海报所指出的,预处理器在将宏拆分为参数之前不会展开arglist中的宏。但是,只要宏不使用 # ## ,它在将宏替换为宏体之前展开args中的宏,因此一个额外的间接寻址可以完成此任务。

        5
  •  0
  •   George Godik    14 年前

    看看Boost_Foreach-它能满足你的需求

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

        6
  •  0
  •   zmbush    14 年前

    预处理器不展开 IN 直到它将参数读入 FOREACH .

    我非常确信C++预处理器只是一个通道,所以你必须使用:

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