C++ 预处理器宏循环__VA_ARGS__ 1 与 2+ 参数
C++ Preprocessor macro loop __VA_ARGS__ 1 vs 2+ arguments
我正在使用这篇文章中的宏来循环我的论点。一切都很好!但是,有没有办法将这两种CCB_CREATE
和CCB_CREATE_MORE
结合起来?
我需要提取第一个参数object_type
来编写其他代码。附加object_type
将使用FOR_EACH
循环插入到映射中。
当我在使用CCB_CREATE_MORE(Type1)
时只有一个参数时,编译器会抱怨。为了解决这个问题,我制作了另一个宏来处理该CCB_CREATE(Type1)
。希望找到一个聪明的解决方案,将这两者组合成一个优雅的宏。有什么想法吗?
#define INSERT_LOADER_MAP(object_type) loader_map.insert(make_pair(#object_type, object_type##Loader::loader()))
#define CCB_CREATE_MORE(object_type,...)
static CCNode * create##object_type##Node() {
std::map<std::string, CCNodeLoader*> loader_map;
std::string classname = #object_type;
FOR_EACH(INSERT_LOADER_MAP,object_type,__VA_ARGS__);
return loadCCBFile((classname + ".ccbi").c_str(), loader_map);
}
#define CCB_CREATE(object_type)
static CCNode * create##object_type##Node() {
std::map<std::string, CCNodeLoader*> loader_map;
std::string classname = #object_type;
INSERT_LOADER_MAP(object_type);
return loadCCBFile((classname + ".ccbi").c_str(), loader_map);
}
当可变参数列表为空时,编译器可能会抱怨尾随逗号。 GCC 和 Visual Studio 编译器支持非标准扩展##__VA_ARGS__
以抑制尾随逗号:
#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
Visual Studio 编译器还将禁止尾随逗号,即使没有 ##
扩展名。
请参阅此处的 GCC 文档和此处的 Visual Studio 文档。
如果您需要符合标准的解决方案,请在回答此问题
时详细说明。因此,如果您使用的是 gcc 或 Visual Studio,您应该能够通过以下简单更改使用原始宏:
#define CCB_CREATE(object_type,...)
static CCNode * create##object_type##Node() {
std::map<std::string, CCNodeLoader*> loader_map;
std::string classname = #object_type;
FOR_EACH(INSERT_LOADER_MAP,object_type,##__VA_ARGS__);
return loadCCBFile((classname + ".ccbi").c_str(), loader_map);
}
编辑:您还需要在FOR_EACH()
宏中使用##__VA_ARGS__
扩展,或者使用ugoren建议的更优雅的修改。
#define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, ##__VA_ARGS__), what, x, __VA_ARGS__)
除了 Chris Olsen 的建议之外,还需要对FOR_EACH
宏稍作更改:
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
结果,FOR_EACH(X, a)
将变得X(a)
(而不是X(a); X();
)。这消除了空的INSERT_LOADER_MAP
调用。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何修复带有 clang 的参数'args'缺少默认参数的问题?
- 折叠表达式和参数包:static_assert 内 Args&& 和 Args 之间的区别
- 在C++中,如何将参数添加到"Args&&... args"参数列表中?
- 作为参数的'char *args[]'和'char **argv'之间的差异
- 我希望通过使用模板元编程从变量ARGS中进行剥离参数
- 声明类型包含未展开的参数包'Args'
- 如何将带有 args 的成员函数作为参数传递给另一个成员函数
- 使用Args.中的n个参数..从位置m开始
- 警告:格式 [-Wformat-extra-args] 的参数太多
- 混合类型,可变长度参数列表(varargin,*args,..)用于C++
- *v8::String::Utf8Value(args[0]->ToString()) 不返回 node 的字符串.js addon 参数
- 可变参数模板转换为 std::function<R(ARGS...)>适用于 GCC 而不是 MSVC2013,为什么?
- 在c++中的fn调用中,args被复制到相应的参数中.这是初始化还是赋值
- 可变参数函数:表达式包含未展开的参数包'args'