【问题标题】:Is it possible to use variadic macros to declare multiple inheritance?是否可以使用可变参数宏来声明多重继承?
【发布时间】:2023-04-10 02:38:01
【问题描述】:

我编写了一个很大程度上依赖于编译时机制的消息传递系统。要接收消息,您可以从类模板继承,如下所示:

class WorldRenderer : public fea::MessageReceiver<SpriteCreateMessage>,
                      public fea::MessageReceiver<SpritePositionMessage>,
                      public fea::MessageReceiver<SpriteMoveMessage>
{
public:
    void handleMessage(const SpriteCreateMessage& mess) override;
    void handleMessage(const SpritePositionMessage& mess) override;
    void handleMessage(const SpriteMoveMessage& mess) override;
};

我认为有一种方法可以使用宏以一种简洁的方式简写这个符号。我如何想象要使用的宏:

class WorldRenderer
FEA_IS_RECEIVER(SpriteCreateMessage, SpritePositionMessage, SpriteMoveMessage)
{
public:
    void handleMessage(const SpriteCreateMessage& mess) override;
    void handleMessage(const SpritePositionMessage& mess) override;
    void handleMessage(const SpriteMoveMessage& mess) override;
};

有没有办法创建这样的 FEA_IS_RECEIVER 宏?

我研究了可变参数宏,但似乎无法评估它们,除非您为每个特定数量的参数编写特定的宏重载。这种方法可行,但会限制您可以订阅的消息数量。

有没有一种巧妙的方法来实现我想要做的事情?

【问题讨论】:

    标签: c++11 macros preprocessor variadic-macros


    【解决方案1】:

    添加一组中间类怎么样:

    template <typename T>
    struct MiddleRenderer : T
    {
        void handleMessage(const SpriteCreateMessage& mess) override
        {
            // ...
        }
    };
    
    template <typename ...Args>
    class WorldRenderer : public MiddleRenderer<Args>...
    {
        // ...
    };
    

    现在您可以使用WorldRenderer&lt;SpriteCreateMessage, SpriteMoveMessage&gt; 等并获得一个派生自所有列出的类的类。

    【讨论】:

    • 这将是一个可能的最终用户解决方案,但我的消息系统是一个库的一部分,它不知道用户将定义哪些消息类型,我正在寻找一个要包含的宏在图书馆。不过还是谢谢
    • @Tobias:看看 Boost.Preprocessor,它有一些相当先进的东西。
    【解决方案2】:

    我认为您正在寻找的语法不会起作用。也许这样的东西同样有用:

    class WorldRenderer :
      FEA_IS_RECEIVER(SpriteCreateMessage),
      FEA_IS_RECEIVER(SpritePositionMessage),
      FEA_IS_RECEIVER(SpriteMoveMessage)
    {
    public:
        void handleMessage(const SpriteCreateMessage& mess) override;
        void handleMessage(const SpritePositionMessage& mess) override;
        void handleMessage(const SpriteMoveMessage& mess) override;
    };
    

    【讨论】:

    • 是的,那行得通。但是 IMO 几乎与没有宏的原始案例一样冗长,因此没有那么多意义。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 2014-05-15
    • 2021-07-07
    • 2010-12-24
    • 2010-09-25
    • 1970-01-01
    相关资源
    最近更新 更多