我需要做一个循环,我将这个简单的反射示例转换为:
std::string mystring[3] = {{"mystring[0]"},{"mystring[1]"},{"mystring[2]"}};
为更长的数组创建一个更可管理的形式。解决方案听起来像我应该使用带循环的宏或递归。但是,宏不支持循环或递归!
如何创建一个宏来随意处理这个问题?
#define NAME_OBJ(type, name, size)
答案 0 :(得分:5)
尝试使用Boost。如果失败,请尝试使用更多Boost。
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/comma_if.hpp>
#include <boost/preprocessor/stringize.hpp>
#define DETAIL_NAME_OBJ_ELEM(z, n, name) \
BOOST_PP_COMMA_IF(n) { BOOST_PP_STRINGIZE(name) "[" BOOST_PP_STRINGIZE(n) "]" }
#define NAME_OBJ(type, name, size) \
type name[size] = { BOOST_PP_REPEAT(size, DETAIL_NAME_OBJ_ELEM, name) }
然后这个:
NAME_OBJ(std::string, mystring, 3);
......扩展到:
std::string mystring[3] = {
{ "mystring" "[" "0" "]" },
{ "mystring" "[" "1" "]" },
{ "mystring" "[" "2" "]" }
};
...然后在编译之前自动合并相邻的字符串文字。
答案 1 :(得分:0)
基于这里处理宏的一个很好的答案 https://stackoverflow.com/a/12540675/1723954
我修改/简化了这个特定案例的解决方案:
#define NAME_OBJ(type, name, size) \
type name[size] = { INIT_ELEMENT_ ## size(name) }
#define INIT_ELEMENT_1(name) { #name "[0]" }
#define INIT_ELEMENT_2(name) INIT_ELEMENT_1(name), { #name "[1]" }
#define INIT_ELEMENT_3(name) INIT_ELEMENT_2(name), { #name "[2]" }
...
该解决方案不允许非常非常大的数组,只有您愿意编码的数组。我做了128,这对我项目中的所有案例都很好。
答案 2 :(得分:0)
正如您所说,C ++中的宏不支持循环或递归,因此您必须复制代码行。
解决此类主题的常用方法是编写程序 - 比方说myGenerator
,其中包含“普通”C ++循环,其输出是C ++源文件(.cpp或.h)。在构建程序的其余部分之前,在构建步骤中集成一个对myGenerartor
的调用。