【问题标题】:Using boost preprocessor to stringize a tuple使用 boost 预处理器对元组进行字符串化
【发布时间】:2016-01-24 08:16:38
【问题描述】:

我是使用 boost 预处理器的初学者。我想使用这个库从一个元组生成一个名称,例如我有一个像这样的元组(float, string, int, bool),我想构造像这样的"Foo<float, string, int, bool>"。我认为使用BOOST_PP_STRINGIZEBOOST_PP_CATBOOST_PP_REPEAT 一定很容易,但不幸的是我找不到生成我想要的字符串的方法。

请给我一个关于创建这个字符串的建议。 Foo 是类名,在预处理过程中自动生成元组。

【问题讨论】:

    标签: c++ boost boost-preprocessor


    【解决方案1】:

    您可以使用BOOST_PP_TUPLE_ENUM 来获取元组元素的逗号分隔扩展。然后,您可以使用#__VA_ARGS__ 对结果列表进行字符串化。 See it live:

    #define STRINGIZE_ALL_I(...) #__VA_ARGS__
    #define STRINGIZE_ALL(...) STRINGIZE_ALL_I(__VA_ARGS__)
    
    #define MAKE_STRING(tuple) STRINGIZE_ALL(Foo<BOOST_PP_TUPLE_ENUM(tuple)>)
    
    // "Foo<float, string, int, bool>"
    MAKE_STRING((float, string, int, bool))
    

    STRINGIZE_ALL_I 存在的原因与您在 STRINGIZECONCAT 中有一个额外的层相同的原因 - 在字符串化之前评估宏。在这种情况下,如果您忽略了两层,您将得到一个包含 BOOST_PP_TUPLE_ENUM((…)) 的字符串。

    请注意,STRINGIZE_ALL 是使用参数列表 Foo&lt;floatstringintbool&gt; 调用的。这是四个参数,而不是一个。


    如果可变参数宏不可用(例如,C++98),您可以利用 "abc" "def" 将被编译器转换为 "abcdef" 的事实。 See it live:

    #define STRINGIZE_ALL_MACRO(s, state, x) state "," BOOST_PP_STRINGIZE(x)
    
    #define STRINGIZE_ALL(seq)      \
        BOOST_PP_SEQ_FOLD_LEFT(     \
            STRINGIZE_ALL_MACRO,    \
            BOOST_PP_STRINGIZE(BOOST_PP_SEQ_HEAD(seq)), \
            BOOST_PP_SEQ_TAIL(seq)  \
        )
    
    #define MAKE_STRING(size, tuple) \
        STRINGIZE_ALL(               \
            BOOST_PP_TUPLE_TO_SEQ(   \
                size,                \
                (Foo<BOOST_PP_TUPLE_ENUM(size, tuple)>) \
            )                        \
        )
    
    // "Foo<float" "," "string" "," "int" "," "bool>"
    MAKE_STRING(4, (float, string, int, bool))
    

    对于这个版本,您的自动生成的元组也必须生成一个大小。完全可以生成一个元组(size, (elems)),您可以将其与此宏一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-20
      • 2011-10-22
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      相关资源
      最近更新 更多