首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C/C++宏中的逗号

C/C++宏中的逗号
EN

Stack Overflow用户
提问于 2012-12-12 23:00:23
回答 7查看 45.4K关注 0票数 118

假设我们有一个这样的宏

代码语言:javascript
复制
#define FOO(type,name) type name

我们可以像这样使用

代码语言:javascript
复制
FOO(int, int_var);

但并不总是如此简单:

代码语言:javascript
复制
FOO(std::map<int, int>, map_var); // error: macro "FOO" passed 3 arguments, but takes just 2

当然我们可以这样做:

代码语言:javascript
复制
 typedef std::map<int, int> map_int_int_t;
 FOO(map_int_int_t, map_var); // OK

这不是很符合人体工程学。另外,必须处理类型不兼容的问题。你知道怎么用宏解决这个问题吗?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-12-12 23:16:10

由于尖括号也可以表示(或出现在)比较运算符<><=>=中,因此宏扩展不能像在圆括号中那样忽略尖括号中的逗号。(这对于方括号和大括号也是一个问题,即使它们通常作为平衡对出现。)您可以将宏参数括在括号中:

代码语言:javascript
复制
FOO((std::map<int, int>), map_var);

然后,问题是参数在宏展开式中仍然是用括号括起来的,这阻止了它在大多数上下文中被读取为一个类型。

解决这个问题的一个很好的技巧是,在C++中,您可以使用函数类型从带括号的类型名中提取typename:

代码语言:javascript
复制
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define FOO(t,name) argument_type<void(t)>::type name
FOO((std::map<int, int>), map_var);

由于形成函数类型会忽略额外的圆括号,因此可以在类型名称不包含逗号的情况下使用带括号或不带括号的此宏:

代码语言:javascript
复制
FOO((int), int_var);
FOO(int, int_var2);

当然,在C中,这不是必需的,因为类型名称不能包含括号内的逗号。因此,对于跨语言的宏来说,你可以这样写:

代码语言:javascript
复制
#ifdef __cplusplus__
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define FOO(t,name) argument_type<void(t)>::type name
#else
#define FOO(t,name) t name
#endif
票数 127
EN

Stack Overflow用户

发布于 2013-11-08 00:36:17

如果您不能使用括号,并且您不喜欢Mike的SINGLE_ARG解决方案,那么只需定义一个逗号:

代码语言:javascript
复制
#define COMMA ,

FOO(std::map<int COMMA int>, map_var);

如果您想将一些宏参数串行化,这也很有帮助,如

代码语言:javascript
复制
#include <cstdio>
#include <map>
#include <typeinfo>

#define STRV(...) #__VA_ARGS__
#define COMMA ,
#define FOO(type, bar) bar(STRV(type) \
    " has typeid name \"%s\"", typeid(type).name())

int main()
{
    FOO(std::map<int COMMA int>, std::printf);
}

它打印std::map<int , int> has typeid name "St3mapIiiSt4lessIiESaISt4pairIKiiEEE"

票数 139
EN

Stack Overflow用户

发布于 2012-12-12 23:08:00

如果您的预处理器支持各种宏:

代码语言:javascript
复制
#define SINGLE_ARG(...) __VA_ARGS__
#define FOO(type,name) type name

FOO(SINGLE_ARG(std::map<int, int>), map_var);

否则,它会更加单调乏味:

代码语言:javascript
复制
#define SINGLE_ARG2(A,B) A,B
#define SINGLE_ARG3(A,B,C) A,B,C
// as many as you'll need

FOO(SINGLE_ARG2(std::map<int, int>), map_var);
票数 67
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13842468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档