【问题标题】:Too much combination to expand a macro太多组合来扩展宏
【发布时间】:2021-11-30 07:24:45
【问题描述】:

我想将一个函数应用于数据缓冲区,并且它们的类型在运行时是已知的。 我为此使用了一个模板函数template <typename T1, typename T2, typename T3> void myFunction()

myFunction 是一个类的成员,该类还包含存储缓冲区的数据结构。缓冲区存储在 char* 指针中,我有一个枚举来了解缓冲区的实际数据类型,从而允许我将指针转换为正确的类型。 我也有一个数据结构来以这种方式注册所有数据类型组合:

// functionPtr is declared earlier
functionPtr = static_cast<void(*)(void)>( &myFunction< DataType1, DataType2, DataType3 >);
registerFunction(functionPtr);

最后,我写了一个宏来解析每种类型的组合。

我的问题是,对于编译器来说,要扩展的数据似乎太多了。我简化为下面的最小示例:

Preproc,915 字节

#include <boost/preprocessor.hpp>

// List the possible types
#define STRIP_ALL_TYPES         \
    (eIBT_Int8)(eIBT_UInt8)     \
    (eIBT_Int16)(eIBT_UInt16)   \
    (eIBT_Int32)(eIBT_UInt32)   \
    (eIBT_Real32)               \
    (eIBT_Binary)               \
    (eIBT_Label16)(eIBT_Label32)

# Generate all the combinations
#define GENERATE_TYPE_COMBINATION(r, product) (product)

// Generate the instruction for a given type combination
#define TEMPLATE_SPECIFIC_TYPE_COMBINATION(r, data, elem)\
functionPtr = static_cast<void(*)(void)>(\
                &CurProcessorType::myFunction< BOOST_PP_SEQ_ENUM(elem) >);

// Generate all the possible instructions
#define GENERATE_TEMPLATE(ST)\
BOOST_PP_SEQ_FOR_EACH(TEMPLATE_SPECIFIC_TYPE_COMBINATION, _, \
                      BOOST_PP_SEQ_FOR_EACH_PRODUCT(GENERATE_TYPE_COMBINATION, ST))

GENERATE_TEMPLATE((STRIP_ALL_TYPES)(STRIP_ALL_TYPES)(STRIP_ALL_TYPES))

Try it online!

通过扩展宏,编译器编译生成的行应如下所示:

functionPtr = static_cast<void(*)(void)>( &CurProcessorType::myFunction< eIBT_Label16, eIBT_Label16, eIBT_Label16 >);

但是当我在 TIO 上测试我的代码时,我收到了错误 .code.tio:23:1: error: macro "BOOST_PP_IIF_1" requires 2 arguments, but only 1 given GENERATE_TEMPLATE((STRIP_ALL_TYPES)(STRIP_ALL_TYPES)(STRIP_ALL_TYPES))

它仅适用于 STRIP_ALL_TYPES 中的少数项目。

有没有我可以用来编译的解决方法?

谢谢

【问题讨论】:

  • 您是否尝试生成 1000 个模板特化?如果 myfunction 不是静态的,static_cast&lt;void(*)(void)&gt; 也是非法的 csst。
  • 是的,我需要 1000 个专业。感谢您提供有关void(*)(void) 的提示。我想尽可能简单地开始,但我也修改了原型,它工作正常。

标签: c++ boost c-preprocessor


【解决方案1】:

我不确定你想用BOOST_PP_SEQ_FOR_EACH 实现什么,因为BOOST_PP_SEQ_FOR_EACH_PRODUCT 已经为你提供了模板参数的所有排列:

#include <boost/preprocessor.hpp>

// List the possible types
#define STRIP_ALL_TYPES         \
    (eIBT_Int8)(eIBT_UInt8)     \
    (eIBT_Int16)(eIBT_UInt16)   \
    (eIBT_Int32)(eIBT_UInt32)   \
    (eIBT_Real32)               \
    (eIBT_Binary)               \
    (eIBT_Label16)(eIBT_Label32)

// Generate all the combinations
#define GENERATE_TYPE_COMBINATION(r, product)\
    functionPtr = static_cast<void(*)(void)>(\
                  &CurProcessorType::myFunction< BOOST_PP_SEQ_ENUM(product) >);

#define GENERATE_TEMPLATE(ST)\
    BOOST_PP_SEQ_FOR_EACH_PRODUCT(GENERATE_TYPE_COMBINATION, ST)

GENERATE_TEMPLATE((STRIP_ALL_TYPES)(STRIP_ALL_TYPES)(STRIP_ALL_TYPES))

Try it online!

另外,我应该注意,如果CurProcessorType::myFunction 是非静态成员函数,则转换为void(*)(void) 是无效的。您应该使用成员函数指针类型。

【讨论】:

  • 我实际上需要处理product的每一项添加前缀,这就是我需要使用BOOST_PP_SEQ_FOR_EACH的原因。你帮助我以不同的方式重写了宏,现在它似乎可以工作了。谢谢您的帮助。我还更改了函数签名。我想尽可能简单地开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多