我正在使用此帖子中的宏循环遍历我的参数.一切都很棒!但是,有没有办法这两个结合起来CCB_CREATE,并CCB_CREATE_MORE?
我需要提取第一个参数object_type来编写其他代码.附加的object_types将使用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); \
}
Run Code Online (Sandbox Code Playgroud)
当可变参数列表为空时,编译器可能会抱怨尾随逗号.GCC和Visual Studio编译器支持非标准扩展##__VA_ARGS__来抑制尾随逗号:
#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
即使没有##扩展名,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); \
}
Run Code Online (Sandbox Code Playgroud)
编辑:
您还需要##__VA_ARGS__在FOR_EACH()宏中使用扩展名,或者使用ugoren建议的更优雅的修改.
#define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, ##__VA_ARGS__), what, x, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)