为什么自动变体与(等效?)函数的模板版本相比不起作用?

问题描述 投票:0回答:1

我正在开发一个 C++ 项目,我想将事件分派到不同的模块。我有一个基本事件类和几个派生事件类型(EventA、EventB、EventC)。我的模块继承自模板化模块基类,该基类使用概念和 SFINAE 将事件分派到派生类中的处理程序(如果已定义)。

它可以与模板一起正常工作,但在尝试仅使用 auto 关键字来实现它时则不行。

这是一个具有完整上下文的工作版本:

struct Event {};
struct EventA : Event {};
struct EventB : Event {};
struct EventC : Event {};

class MyModule;

template <typename T>
concept IsEventType = std::is_base_of_v<Event, T>;

template <typename Dispatcher, typename Dispatchable>
concept CanDispatch = requires(Dispatcher* d, const Dispatchable& e)
{
    { d->dispatch(e) };
};


template <typename Derived>
class Module
{
public:

    void onEvent(const IsEventType auto& e)
    {
        dispatchEvent(e, static_cast<Derived*>(this));
    }

private:

    // This is the problematic function
    template<IsEventType Dispatchable, CanDispatch<Dispatchable> Dispatcher>
    void dispatchEvent(const Dispatchable& e, Dispatcher* dispatcher)
    {
        dispatcher->dispatch(e);
    }

    void dispatchEvent(...) {}
};


class MyModule : public Module<MyModule>
{
public:
    void dispatch(const EventA& event) {
        std::cout << "Handling EventA in MyModule" << std::endl;
    }

    void dispatch(const EventB& event) {
        std::cout << "Handling EventB in MyModule" << std::endl;
    }
};


int main()
{
    MyModule m;

    m.onEvent(EventA{});
    m.onEvent(EventB{});
    m.onEvent(EventC{});
}

我尝试编写这个而不是模板版本,但它永远不会被调用

// Also tried CanDispatch<std::remove_cvref_t<decltype(e)>>
void dispatchEvent(const IsEventType auto& e, CanDispatch<decltype(e)> auto* dispatcher)
{
    dispatcher->dispatch(e);
}
  • P.S.1。另外,如果有人可以推荐我一种更干净、更简洁的方法,我会很高兴。
  • PS2。在这种情况下,有没有办法避免在基函数之前声明派生函数?
c++ c++20 sfinae c++-concepts c++-templates
1个回答
0
投票

这似乎是另一个 msvc 错误,在最新的 trunk 版本中已修复

© www.soinside.com 2019 - 2024. All rights reserved.