Reputation: 37
Currently trying to implement an event handler for an SDL project. The general idea is that user input events will be handled via Message
objects, that will be able to carry around callbacks with different signatures.Currently, what I have is :
#pragma once
#include<functional>
#include"Entity.h"
#include"Enums.h"
typedef std::function<void(void)> VoidCallback;
typedef std::function<void(const Entity& entity)> EntityCallback;
template<typename Functor>
class Message
{
private:
MessageType message;
public:
Message(MessageType message, Functor callback) :message(message), callback(callback) {};
~Message();
};
However, this arrangement makes it difficult to pass different types of callbacks to different listeners. The current listener implementation is
#include"Message.h"
class Listener
{
public:
virtual void onNotify(Message<>& event) = 0;
};
which which causes errors. What would be the best way to resolve this issue?
Upvotes: 2
Views: 116
Reputation: 371
You cannot have a template virtual function
Can a C++ class member function template be virtual?
#include "Message.h"
class Listener
{
public:
//you may use a template function as such
template<class func>
void onNotify(Message<func>& event) { /*must implement*/ }
//or specialize for specific function calls
virtual void onNotify(Message<some_known_func>& even) = 0;
};
If you want to utilize template-methods with a virtual-like features you may be interested in looking into CRTP. (CRTP enables the super-class to call the subclasses methods)
Upvotes: 1
Reputation: 4386
It is not possible for a virtual function to be templated.
Virtual function are called through a vtable
, which is basically an array of function pointer. Each virtual method in a base class takes up a slot in the virtual table. Obviously the virtual table size needs to be known at compile time, because it is part of the object definition.
class Base {
public:
virtual void hello(){};
virtual void bye(){};
}
The vtable could look like this:
hello
.bye
.So the vtable needs 2 functions pointer.
Now if either hello()
or bye()
were to be templated, how could we create a vtable?
hello<int>()
hello<char>()
.We cannot know in advance all the variation of the templated function so it's not possible to build a vtable.
Upvotes: 1