C++ 从预处理器标记创建字符串数组
我有一个令牌列表,我想从中创建一个枚举(平凡)和一个字符串数组(稍后用于创建字符串到枚举的映射)。以下是我的尝试:C++ 从预处理器标记创建字符串数组,c++,c-preprocessor,c++03,boost-preprocessor,C++,C Preprocessor,C++03,Boost Preprocessor,我有一个令牌列表,我想从中创建一个枚举(平凡)和一个字符串数组(稍后用于创建字符串到枚举的映射)。以下是我的尝试: #define TOKEN_LIST CUBE , SPHERE , CIRCLE #define CREATE_ARRAY_OF_STRINGS( ... ) const char* token[] = { __VA_ARGS__ }; CREATE_ARRAY_OF_STRINGS( TOKEN_LIST ) // enum SHAPE_TYPE{ TOKEN_LIS
#define TOKEN_LIST CUBE , SPHERE , CIRCLE
#define CREATE_ARRAY_OF_STRINGS( ... ) const char* token[] = { __VA_ARGS__ };
CREATE_ARRAY_OF_STRINGS( TOKEN_LIST )
// enum SHAPE_TYPE{ TOKEN_LIST }; // easy
int main(int argc, char *argv[])
{
return 1;
}
问题是当我使用-E
标志编译时,标记列表
没有如图所示进行字符串化,如下所示:
const char* token[] = { CUBE , SPHERE , CIRCLE };
int main(int argc, char *argv[])
{
return 1;
}
其中const char*token[]={CUBE,SPHERE,CIRCLE}代码>应该是const char*token[]={“立方体”、“球体”、“圆”}代码>
使用C++03还有其他方法可以实现这一点吗?可能是Boost Processor?如果您愿意稍微更改令牌列表的格式,您可以轻松地使用
下面是一个使用Boost.preprocesser序列而不是逗号分隔列表的示例:
#define GENERATE_STRING(maZ, maIdx, maTokens) \
BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(maIdx, maTokens))
#define GENERATE_STRINGS(maTokens) \
BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(maTokens), GENERATE_STRING, maTokens)
#define TOKEN_LIST (CUBE)(SPHERE)(CIRCLE)
const char* token[] = { GENERATE_STRINGS(TOKEN_LIST) }
enum ShapeType {
BOOST_PP_SEQ_ENUM(TOKEN_LIST)
};
由于您似乎有权访问..
和\uu VA\u ARGS\uuu
(这不是C++03特性),因此您也应该能够使用Boost.Preprocessor元组(括号中以逗号分隔的列表);由于支持可变宏,Boost.Preprocessor能够隐式地确定元组大小。但是,我没有这方面的经验,因此我无法提供代码示例
maZ
参数是Boost.Preprocessor重复宏的一个实现特性。有三种:z(用于枚举样式函数)、d(用于while样式函数)和r(用于样式函数)。它只在嵌套这些构造时有用,因为它允许更快的预处理。如果GENERATE_STRING
本身正在调用一个enum函数,那么在预处理器上使用BOOST_PP_enum_#maZ
比只使用BOOST_PP_enum
进行嵌套调用(但后者也可以工作,只要不超过编译器的预处理限制)。为什么需要这个?如果您使用宏,这意味着您在代码开始执行之前就知道了。因此,您可以将它们存储在变量中。和用于创建数组或在数组初始化中直接使用它们。以便自动更新字符串到枚举的映射。我只想在一个点上注册令牌,并自动更新枚举列表和映射。但是这不是我需要帮助的部分。maZ
在GENERATE_STRING()
中扮演什么角色?@Olumide.谢谢。为什么所有参数都以ma
开头?z
的情况也很重要。我这样问是因为您在代码和解释中使用了不同的大小写。@大小写(和拼写)一点都不重要,它们和其他任何参数一样都是宏参数ma
只是我个人在m
acroa
rguments前面加前缀的编码风格。