I have some code that deal with many pointer to function of different signature. Here's a snippet:
#include <unordered_map>
// Simple type id system
template<typename> void type_id(){}
using type_id_t = void(*)();
// value type of our map. We reinterpret functions pointer to this type
using held_type = void(*)();
// actual function type.
template<typename T>
using funct_type = T(*)();
int main() {
std::unordered_map<type_id_t, held_type> function_map;
function_map.emplace(type_id<int>, reinterpret_cast<held_type>(
static_cast<func_type<int>>([]() -> int { return 42; });
));
function_map.emplace(type_id<double>, reinterpret_cast<held_type>(
static_cast<func_type<double>>([]() -> double { return 9.4; });
));
// later on
// prints 42
std::cout << reinterpret_cast<func_type<int>>(function_map[type_id<int>])();
// prints 9.4
std::cout << reinterpret_cast<func_type<double>>(function_map[type_id<double>])();
}
Is there a way to achieve similar result without significant overhead and without reinterpret casts?
If you can rework a bit your functions, you could approach it by reversing the flow and removing the return type.
Here is an example of what I mean:
#include <unordered_map>
#include <iostream>
template<typename T>
void call(T t, void *ptr) {
*static_cast<T *>(ptr) = t;
}
// Simple type id system
template<typename> void type_id() {}
using type_id_t = void(*)();
// value type of our map. We reinterpret functions pointer to this type
using held_type = void(*)(void *);
// actual function type.
template<typename T>
using funct_type = T(*)();
int main() {
std::unordered_map<type_id_t, held_type> function_map;
function_map.emplace(type_id<int>, +[](void *ptr){ return call(42, ptr); });
function_map.emplace(type_id<double>, +[](void *ptr) { call(9.4, ptr); });
// prints 42
int i;
function_map[type_id<int>](&i);
std::cout << i << std::endl;
// prints 9.4
double d;
function_map[type_id<double>](&d);
std::cout << d << std::endl;
}
See it up and running on wandbox.
Probably you can use the type of the variable to pick the right specialization of type_id
up when you query function_map
. Just hide everything behind a function template.