为什么这个不能编译?如何实现才能编译?
这是我正在使用的一些 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
其他人已经解释了为什么它不能按原样编译。
为了使它工作,你必须给
IN
一个机会变成逗号。为此,您可以在宏定义中引入额外级别的“间接”。在这种情况下,您必须使用逗号的替代品(例如
IN
),并且不能再显式指定逗号。即现在编译得很好,但
不行。
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 definitionIn this case you'll have to use some substitute for comma (like your
IN
) and can no longer specify comma explicitly. I.e. now thiscompiles fine, while
does not.
编译器在读取
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 toFOREACH
. 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 useFOREACH(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.
在您的示例中,
IN
的扩展没有发生得足够早,但您可以将扩展版本传递给另一个宏:Expansion for
IN
doesn't happen early enough in your example, but you can pass the expanded version to another macro:正如之前的发帖者所指出的,预处理器在将 arglist 拆分为参数之前不会扩展 arglist 中的宏。但是,只要宏不使用
#
或##
,它就会在将 args 中的宏替换到宏主体中之前对其进行扩展,因此需要额外的间接寻址诡计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查看 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
预处理器在读取
FOREACH
的参数之前不会将IN
扩展为逗号。我很确定 c++ 预处理器只能通过一次,因此您必须使用:
The preprocessor doesn't expand the
IN
to a comma until after it reads the arguments toFOREACH
.I'm pretty sure that the c++ preprocessor is one pass only, so you'll have to use: