如何从内部别名推断模板参数?

Gas*_*sim 5 c++ templates

我有一个带有两个参数的模板类:

template<class TEvent, class TData>
class EventPool {
public:
  using EventObserver = std::function<void(const TData &)>;
  using EventData = TData;
  using EventType = TEvent;

public:
  EventObserverId observe(TEvent event, EventObserver &&observer) { ... }
  void deleteObserver(EventObserverId observerId) { ... }
  void dispatch(TEvent event, const TData &data) { ... }
};
Run Code Online (Sandbox Code Playgroud)

我还有另一个存储许多池的容器类:

class EventSystem {
  using CollisionPool = EventPool<CollisionEvent, CollisionData>;
  using MouseButtonPool = EventPool<MouseButtonEvent, MouseButtonData>;
  using KeyboardPool = EventPool<KeyboardButtonEvent, KeyboardButtonData>;
public:


private:
  std::tuple<CollisionPool, MouseButtonPool, KeyboardPool> mPools;
};
Run Code Online (Sandbox Code Playgroud)

现在,我想创建一个基于模板的函数,它自动推断正确的池并调用池内的函数。例如:

template<class TEvent>
EventObserverId observe(TEvent event, DeriveThePoolHere::EventObserver &&observer) {
  auto &pool = getPoolByFromEventType<TEvent>();
  return pool.observe(event, observer);
}

template<class TEvent>
void deleteObserver(TEvent event, EventObserverId observerId) {
  auto &pool = getPoolFromEevntType<TEvent>();
  pool.deleteObserver(observerId);
}

void dispatch(TEvent event, const DeriveThePoolHere::EventData &data) {
  auto &pool = getPoolFromEventType<TEvent>();
  pool.dispatch(event, data);
}
Run Code Online (Sandbox Code Playgroud)

如果我能以某种方式创建一个将事件映射到事件数据的类型映射,我就可以解决这个问题,但我不知道如何在 C++ 中做到这一点。

sp2*_*nny 1

if constexpr在and的帮助下std::apply(需要 c++17)
也许像这样:

template<typename TPool, typename TEvent, typename TData>
void dispatchIfMatch(TPool& pool, TEvent event, const TData& data) {
    if constexpr(std::is_same<TEvent, typename TPool::EventType>::value) {
        pool.dispatch(event, data);
    }
}

template<typename TEvent, typename TData>
void dispatch(EventSystem& esys, TEvent event, const TData& data) {
    std::apply(
        [&](auto&&... args) {
            ((dispatchIfMatch(args, event, data)), ...);
        }, esys.mPools);
}
Run Code Online (Sandbox Code Playgroud)

在这里测试:http://coliru.stacked-crooked.com/a/2c2231c860d8023c