c++ - 如何在 STL 容器中存储具有抽象模板类型的抽象模板类?

标签 c++ c++11 templates c++14 cqrs

我希望标题不会误导人,但我找不到合适的语言来定义我在一个问题中的问题。

最近我一直在尝试使用 C++ 实现“CQRS 命令处理程序”设计模式。我有 2 个层次结构,我必须将它们结合在一起:

  • 命令

    struct ICommand
    {
        virtual ~ICommand() = default;
    };
    
    struct SampleCommand : ICommand
    {
        int sampleParameter;
    
        SampleCommand() : sampleParameter(0)
        {
        }
    
        explicit SampleCommand(const int sampleParameter)
        {
            this->sampleParameter = sampleParameter;
        }
    };
    
  • ICommandHandler

    template<typename T, typename = std::enable_if_t<std::is_base_of<ICommand, std::decay_t<T>>::value>>
    struct ICommandHandler
    {
         virtual void Handle(std::shared_ptr<T> command) = 0;
         virtual ~ICommandHandler() = default;
    };
    
    class SampleCommandHandler : public ICommandHandler<SampleCommand>
    {
    public:
        void Handle(std::shared_ptr<SampleCommand> command) override
        {
            std::cout << "sampleParameter " << command->sampleParameter << std::endl;
        }
    };
    

我需要实现的最后一部分是一个调度程序,它接受一个命令,找到一个处理程序并将命令委托(delegate)给找到的处理程序。我想到的第一个想法是在调度程序中公开一些处理程序注册 API 并编写调度方法,该方法将简单地尝试 dynamic_cast 所有已注册的处理程序,如果某些转换成功,它将调用找到的处理程序,如下所示:

class Dispatcher
{
public:

template<typename T>
void Dispatch(std::shared_ptr<T> command)
{
    auto handler = std::find_if(std::begin(_handlers), std::end(_handlers), [](auto handler)
    {
        return dynamic_cast<ICommandHandler<T>*>(handler);
    });

    if(handler != std::end(_handlers))
    {
        (*handler)->Handle(command);
    }
}

private:
    std::vector<?> _handlers;
};

问题是:“_handlers”std::vector 应该存储什么类型才能使 Dispatcher::Dispatch 方法正常工作,如果这可能的话?

到目前为止我尝试了什么:

  • std::vector< ICommandHandler *> - 未编译,因为无法将具体处理程序强制转换为 ICommandHandler< ICommand> *>。

    Error   C2440   'initializing': cannot convert from 'SampleCommandHandler *' to 'ICommandHandler<ICommand,void> *'
    
  • std::vector< void* > - 未编译,因为 dynamic_cast 不能应用于 void*

最佳答案

你在这里有一堆毫无意义的(至少对我来说)多态性;我会根据它们处理的内容拆分处理程序的容器,而不是使用一个 vector 。就像从类型索引到处理程序的映射/无序映射;或者,有一组固定的类型来处理。

但是要解决的问题是:

struct ICommandHandlerBase{
  virtual ~ICommandHandlerBase(){};
};
template<typename T, typename = std::enable_if_t<std::is_base_of<ICommand, std::decay_t<T>>::value>>
struct ICommandHandler:ICommandHandlerBase
{

现在存储 ICommandHandlerBase* 的 vector 或 unique_ptr<ICommandHandlerBase> .

关于c++ - 如何在 STL 容器中存储具有抽象模板类型的抽象模板类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50110140/

相关文章:

c++ - POCO如何发送XML数据?

c++ - 为什么 VC++ 允许没有完整模板参数的模板类实例?

c++ - 我可以定义从 std::function 到 std::shared_ptr<MyClass> 的隐式转换吗?

c++ - 为什么不修改关联容器的键?

c++ - 该代码标准是否合规?

c++ - 将模板化回调函数传递给另一个模板化函数

c++ - 如何确定 C++ 模板参数是否存储唯一键?

c++ - 在范围锁定之前检查可选的互斥锁

c++ - 有没有标准的方法来替换 C 风格的 bool 数组?

c++ - 从 C++ 中的空格读取文件