用模板定义多个函数的C++泛型方法

Cet*_*ric 6 c++ templates template-specialization variadic-templates c++17

在C++中,是否可以根据提供的模板参数的数量定义多个方法?类似于可变函数的工作方式?

有了我能做的功能

template <class ...Args>
struct VariadicFunctionCallback {
    typedef std::function<void(std::shared_ptr<Args>...)> variadic;
};
Run Code Online (Sandbox Code Playgroud)

但我想知道的是,如果我可以做类似的事情,但创建多个函数而不是多个参数

template <class ...FunctionArg>
class Example {
     void Function(FunctionArg)...
}
Run Code Online (Sandbox Code Playgroud)

那将允许我做类似的事情

template <>
class Example<int, float> {
    void Function(int i) {
        ...
    }

    void Function(float f) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这是可能的,那么与我目前的设置相比有什么优势呢

template<class EventType>
class EventHandler {
public:
    void HandleEvent(const std::shared_ptr<EventType>& event) {
    }
};

class ExampleEvent : public Event<ExampleEvent> {

};

class ExampleHandler : public EventHandler<ExampleHandler>, EventHandler<Events::ShutdownEvent> {
public:
    void HandleEvent(const std::shared_ptr<ExampleEvent> &event);

    void HandleEvent(const std::shared_ptr<Events::ShutdownEvent> &event);
};
Run Code Online (Sandbox Code Playgroud)

- 编辑 - 如果两个解决方案,我最终得到了混合.这可能不是最好的,我会继续玩,并加班加点.

template <class EventType>
class BaseEventHandler {
public:
    EventIdentifier GetIdentifier() const {
        return EventType::GetIdentifier();
    }

    virtual void HandleEvent(const std::shared_ptr<EventType> &event) = 0;
};

template<class EventType, class ...EventTypes>
class EventHandler: public BaseEventHandler<EventTypes>... {

};
Run Code Online (Sandbox Code Playgroud)

然后允许我这样做

class EventListener: public EventHandler<ShutdownEvent, MousePosEvent, WindowCloseRequestEvent> {
    void HandleEvent(const std::shared_ptr<ShutdownEvent> &event);
    void HandleEvent(const std::shared_ptr<MousePosEvent> &event);
    void HandleEvent(const std::shared_ptr<WindowCloseRequestEvent> &event);
}
Run Code Online (Sandbox Code Playgroud)

max*_*x66 8

我想你可以做Example一种递归的自我继承课; 某事

    template <typename ...>
    struct Example
     {
       // dummy Function() to end the recursion
       void Function ()
        { }
     };

    template <typename T0, typename ... Ts>
    struct Example<T0, Ts...> : public Example<Ts...>
     {
       using Example<Ts...>::Function;

       void Function (T0 const &)
        { };
     };
Run Code Online (Sandbox Code Playgroud)

所以你可以写

int main ()
 {
   Example<int, long, float>  e0;

   e0.Function(0);
   e0.Function(0L);
   e0.Function(0.0f);
 }
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

OP问

那么可以在此基础上进行专业化吗?

你的意思是如下吗?

template <typename ...>
struct Example
 {
   // dummy Function() to end the recursion
   void Function ()
    { }
 };

template <typename T0, typename ... Ts>
struct Example<T0, Ts...> : public Example<Ts...>
 {
   using Example<Ts...>::Function;

   void Function (T0 const &)
    { };
 };

template <typename ... Ts>
struct Example<float, Ts...> : public Example<Ts...>
 {
   void FunctionFloat (float const &)
    { };
 };

int main ()
 {
   Example<int, long, float>  e0;

   e0.Function(0);
   e0.Function(0L);
   e0.FunctionFloat(0.0f);
   //e0.Function(0.0f); // compilation error
 }
Run Code Online (Sandbox Code Playgroud)