我使用这个宏后通过我的论点循环。一切正常!但是,有没有一种方法可以将两者CCB_CREATE
和结合起来CCB_CREATE_MORE
?
我需要提取第一个参数object_type
来编写其他代码。其他object_type
s将使用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,则可以通过以下简单更改使用原始宏:
#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); \
}
编辑:您也需要##__VA_ARGS__
在FOR_EACH()
宏中使用扩展名,或者使用ugoren建议的更优雅的修改。
#define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, ##__VA_ARGS__), what, x, __VA_ARGS__)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句