从预处理器标记创建字符串数组

时间:2016-01-15 15:19:39

标签: 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_LIST }; // easy

int main(int argc, char *argv[])
{
    return 1;
}

问题是当我使用TOKEN_LIST标志进行编译时,-E没有字符串化,如下所示:

const char* token[] = { CUBE , SPHERE , CIRCLE };

int main(int argc, char *argv[])
{
    return 1;
}

const char* token[] = { CUBE , SPHERE , CIRCLE };应该是const char* token[] = { "CUBE" , "SPHERE" , "CIRCLE" };

有没有其他方法可以用C ++ 03实现这一目标?或许提升处理器?

1 个答案:

答案 0 :(得分:2)

如果您愿意稍微更改TOKEN_LIST的格式,可以使用Boost.Preprocessor轻松完成此操作。

以下是使用Boost.Preprocessor 序列而不是逗号分隔列表的示例:

#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)
};

由于您似乎可以访问...__VA_ARGS__不是 C ++ 03功能),因此您应该可以使用Boost.Preprocessor 元组以及括号中的逗号分隔列表;通过支持可变参数宏,Boost.Preprocessor能够隐式确定元组大小。但是,我没有经验,所以我无法提供代码示例。

maZ参数是Boost.Preprocessor重复宏的实现功能。有三个: z (由枚举式函数使用), d (由while-style函数使用)和 r (由for-style functions)。它仅在嵌套这些结构时有用,因为它允许更快的预处理。如果GENERATE_STRING本身正在调用枚举函数,那么在预处理器上使用BOOST_PP_ENUM_ ## maZ比在嵌套调用中使用BOOST_PP_ENUM更容易(但后者也可以,只要你不要超过编译器的预处理限制。