c++ - 覆盖可变类模板中的多个虚函数

标签 c++ variadic-templates

让我举一个代码示例。

#include <iostream>
#include <utility>
#include <tuple>

template <typename Service>
struct SubscriberImpl {
    virtual void handleService(Service const&) = 0;
};

template <typename...ServiceType>
struct Subscriber : SubscriberImpl<ServiceType>... {

};

struct IntService {};
struct FloatService {};

template <typename StatusUpdatePolicy, typename... ServiceType>
struct StatusUpdater : Subscriber<ServiceType...>
{
    StatusUpdater(StatusUpdatePolicy const& statusUpdater)
    : m_statusUpdater{statusUpdater}
    {}
    // wont work
    void handleService(IntService const& service) override {
        m_statusUpdater.updateService(service);
    }

    void handleService(FloatService const& service) override {
        m_statusUpdater.updateService(service);
    }

    StatusUpdatePolicy m_statusUpdater;
}; 

struct DummyPolicy {
    void updateService(IntService const& service) {
        m_i = 42;
        std::cout << m_i << "\n";
    }

    void updateService(FloatService const& service) {
        m_f = 3.14f;
        std::cout << m_f << "\n";
    }

    int m_i;
    float m_f;
};
int main() {

    StatusUpdater<DummyPolicy, IntService, FloatService> su(DummyPolicy{}); 

    su.handleService(IntService{});
    su.handleService(FloatService{});
}

这里 Subscriber 有一个纯虚函数 handleService(ServiceType const) 用于 pack ServiceType... 中的每个模板参数。所以我必须在 StatusUpdater 上覆盖每一个。在这里,我已经为 IntServiceFloatService 手动提供了我需要的那些,我知道在这个最小的例子中我只需要那些。但我希望能够为包 ServiceType... 中的任何内容提供覆盖。无论如何,它们都会调用给定策略的 updateService 方法。

请注意,Subscriber 来自外部库,我无法修改它的定义。

最佳答案

您不能将此类实现直接放入类中,您必须继承它们(类似于 Subscriber 从多个 SubscriberImpl 实例继承的方式)。然而,要覆盖它们并仍然保持您的类作为 Subscriber 多态使用,您将必须“顺序”而不是“并行”继承它们。此外,Curiously recurring template pattern可用于为所有实现提供对最终覆盖对象的访问权限:

template <class Self, class SubscriberClass, class... ServiceTypes>
struct StatusUpdaterOverride;


template <class Self, class SubscriberClass, class ThisType, class... RemainingTypes>
struct StatusUpdaterOverride<Self, SubscriberClass, ThisType, RemainingTypes...> : StatusUpdaterOverride<Self, SubscriberClass, RemainingTypes...>
{
  void handleService(ThisType const& service) override
  {
    static_cast<Self*>(this)->m_statusUpdater.updateService(service);
  }
  using StatusUpdaterOverride<Self, SubscriberClass, RemainingTypes...>::handleService;
};


template <class Self, class SubscriberClass, class ThisType>
struct StatusUpdaterOverride<Self, SubscriberClass, ThisType> : SubscriberClass
{
  void handleService(ThisType const& service) override
  {
    static_cast<Self*>(this)->m_statusUpdater.updateService(service);
  }
};


template <class StatusUpdatePolicy, class... ServiceType>
struct StatusUpdater : StatusUpdaterOverride<StatusUpdater<StatusUpdatePolicy, ServiceType...>, Subscriber<ServiceType...>, ServiceType...>
{
    StatusUpdater(StatusUpdatePolicy const& statusUpdater)
    : m_statusUpdater{statusUpdater}
    {}

    StatusUpdatePolicy m_statusUpdater;
};

[Live example]

关于c++ - 覆盖可变类模板中的多个虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54941530/

相关文章:

c# - 如何从头开始创建声音 C#

c++ - 为什么boost asio中的async_read将const MutableBufferSequence作为第二个参数?

带有元组的 C++ 可变参数模板

c++ - 在可变参数模板上生成变量列表

c++ - 包扩展不在最后一个参数中的可变参数函数模板

templates - 我怎样才能访问这个嵌套模板参数?

c++ - SFINAE 类型集包含的类型

c++ - 当您不需要从模板继承时,如何从模板类继承?

c++ - 使用 CUDA 中的缩减查找数组中的最小值(但跳过一些元素)

c++ - 编译器错误的单元测试