为什么这个不能编译?如何实现才能编译?

发布于 2024-08-30 06:57:53 字数 1185 浏览 3 评论 0原文

这是我正在使用的一些 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 更改为逗号,代码就会编译。如何让 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;
}

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

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

However, I get an error:

macro "FOREACH" requires 2 arguments, but only 1 given

The code compiles if I change the IN to a comma. How can I get the IN to take the place of a comma?

Update: for those interested, here is the final version, which, if I do say so myself, is quite nice.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深海不蓝 2024-09-06 06:57:53

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

为了使它工作,你必须给 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 } 

在这种情况下,您必须使用逗号的替代品(例如 IN),并且不能再显式指定逗号。即现在

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

编译得很好,但

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

不行。

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.

假装不在乎 2024-09-06 06:57:53

编译器在读取 FOREACH 的参数之前不会扩展 IN 宏。事实上,我认为这是故意的(这样你就可以将逗号传递给宏)。

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

您也可以#define IN(不设置任何内容),然后使用FOREACH(int item, IN ints),这不太好,但可以接受。

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

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.

自我难过 2024-09-06 06:57:53

在您的示例中, IN 的扩展没有发生得足够早,但您可以将扩展版本传递给另一个宏:

#define FOREACH(x) DO_FOREACH(x)
#define DO_FOREACH(x,y) for( ... ) ...

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( ... ) ...
临走之时 2024-09-06 06:57: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 }

正如之前的发帖者所指出的,预处理器在将 arglist 拆分为参数之前不会扩展 arglist 中的宏。但是,只要宏不使用 ###,它就会在将 args 中的宏替换到宏主体中之前对其进行扩展,因此需要额外的间接寻址诡计

#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

萝莉病 2024-09-06 06:57:53

查看 BOOST_FOREACH - 它可以满足您的要求

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

Check out BOOST_FOREACH - it does what you want

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

泡沫很甜 2024-09-06 06:57:53

预处理器在读取 FOREACH 的参数之前不会将 IN 扩展为逗号。

我很确定 c++ 预处理器只能通过一次,因此您必须使用:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文