【问题标题】:Pre-processor macro concatenation to build class function预处理器宏连接以构建类函数
【发布时间】:2015-03-03 16:30:57
【问题描述】:

我需要一个 POD 配置结构数组,其中包含指向某些长名称类中的静态函数的指针,例如

typedef void (*MyFn)();

struct MyData {
    MyFn myFn;
    ...
};

...
struct MyData const configArr[] = {
    { ... },
    ...
};

要使用的函数类似于void AClass::AnotherClass::YetAnotherClass::someFn();

我看到三个选项:

  1. 使configArr成为AClass::AnotheClass::YetAnotherClass的成员,
  2. 在配置中使用全名。而且我不喜欢他们中的任何一个,
  3. 我尝试了通常的两级预处理器连接,它抱怨:

    '粘贴“::”和“xxx”没有给出有效的预处理令牌'。

我想出的最好的办法是为 conf 中使用的所有函数设置一些通用前缀。

即:AClass::...::prefSomeFn();并使用 'AClass::...::pref' 和 'SomeFn' 的串联它可以工作,但它看起来仍然太难看。

有没有更好的出路?

【问题讨论】:

  • 放弃通过宏思想生成代码。考虑类嵌套是否过多。如果经过适当考虑,您决定保持这种复杂性,请添加一些 typedef。考虑命名空间作为替代方案。也许您正在使用类作为命名空间。无论如何,预处理器的限制不是问题:它们可以引导您远离宏,这是正确的。
  • 更好的方法是摆脱:“包含指向某个长名称类中的静态函数的指针的 POD 配置结构数组”。真的。
  • 感谢您的想法。然而,深度嵌套似乎是不可避免的——它是一个包含许多独立组件的大型系统,它们都使用相同的机制。我看不出名称空间有什么帮助。还有关于生成配置未生成代码的问题。
  • 备份并告诉我们更多关于您尝试解决的实际问题的信息可能会有所帮助。
  • @JohnZwink。顶级类是托管对象,下一级是 FSM-slice(也称为正交区域),下一级是 FSM-slice 的动作和守卫的集合,config-table 是 FSM 的转换表(类似于 boost msm,但适用于更大的规模并进行了一些重大改进)。最好让转换表匿名 - 以便更好地解耦生成的和手工制作的代码。

标签: c++ concatenation c-preprocessor


【解决方案1】:

'粘贴“::”和“xxx”没有给出有效的预处理令牌'。

那是因为它们独立的标记;您不需要粘贴它们,只需将它们放在展开中相邻即可:

struct ClassWithALongName { int i; };
#define X(MemberId) &ClassWithALongName::MemberId
auto ptr = X(i);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 2012-04-25
    • 2010-11-11
    • 2015-07-12
    • 2014-04-02
    相关资源
    最近更新 更多