I'd like to have some sort of structure/type/map which can contain std::function
specialisations (to contain my callbacks) which have the type known at compile time, without having to do any sort of virtual inheritance or making all my types inherit from a base type.
e.g. I'd like GenericFunction
in here to hold the std::function
without erasing the known type, so I can get the type later on during the callback()
#include <unordered_map>
#include <string>
#include <functional>
#include <iostream>
// Example struct that I want
template<class CallbackDatatype>
struct GenericFunction{
GenericFunction(const std::function<void(const CallbackDatatype&)> callback)
: m_callback(callback)
std::function<void(const CallbackDatatype&)> m_callback;
static T datatypePlaceholder;
}
class Test
{
public:
Test() = default;
template <class CallbackDatatype>
void attachCallback(const std::string& key, const std::function<void(const CallbackDatatype&)>& callbackFn)
{
// How do I implement GenericFunction/a map that can hold GenericFunction??
m_callbackMap[key] = GenericFunction<CallbackDatatype>(callbackFn)
}
// Called during runtime
void callback(const std::string& key, void* payload)
{
const auto mapIter = m_callbackMap.find(key);
if (mapIter != m_callbackMap.end()) {
// I need to get the datatype of the argument specified in the std::function stored in m_callbackMap to use for deserialising my payload
decltype(mapIter->second.datatypePlaceholder) data = m_deserialiser.deserialise<decltype(mapIter->second.datatypePlaceholder)>(payload);
mapIter->second.m_callback(data);
}
}
private:
Deserialiser m_deserialiser;
std::unordered_map<std::string, GenericFunction> m_callbackMap;
};
struct SomeStruct{
int a;
int b;
float c;
};
int main(){
// Example int function (though I want to use more complicated structs)
const fn1 = [](const int& data) -> void {
std::cout << data << std::endl;
}
const fn2 = [](const SomeStruct& data) -> void {
std::cout << data.c << std::endl;
}
Test test;
test.attachCallback("Route1", fn1);
test.attachCallback("Route2", fn2);
return 0;
}
Is there any way to do this?
Thank you!