#include <iostream>
#include <map>
#include <string>
#include <array>
#include <stdexcept>
// you did not show what 'my_type' actually looks like. As this site does
// not support C++17, so I'm just using a placeholder for demo purposes.
// In C++17 and later, std::variant would make more sense...
struct my_type {
enum {v_int, v_double, v_string} type;
//...
explicit my_type(int i) : type(v_int) { }
explicit my_type(double d) : type(v_double) { }
explicit my_type(std::string s) : type(v_string) { }
};
// As this site does not support C++17, I'm using template specialization
// to handle multiple template parameter types. In C++17 and later,
// 'if constexpr (std::is_same_v<T, ...>)' can be used instead...
template<class T>
std::string my_fun(my_type complex_object)
{
/*
if constexpr (std::is_same_v<T, int>)
return "my_func<int>";
if constexpr (std::is_same_v<T, double>)
return "my_func<double>";
if constexpr (std::is_same_v<T, std::string>)
return "my_func<string>";
*/
return "my_func<T>";
}
template<>
std::string my_fun<int>(my_type complex_object)
{
return "my_func<int>";
}
template<>
std::string my_fun<double>(my_type complex_object)
{
return "my_func<double>";
}
template<>
std::string my_fun<std::string>(my_type complex_object)
{
return "my_func<string>";
}
// now, for the mapping code...
constexpr std::array<const char*,3> my_ids = {"int", "double", "string"};
using my_func_type = std::string(*)(my_type);
const std::map<std::string, my_func_type> my_funcs = {
{"int", &my_fun<int>},
{"double", &my_fun<double>},
{"string", &my_fun<std::string>}
};
const char* get_info(my_type complex_object)
{
return my_ids[complex_object.type];
}
std::string my_disp_fun(my_type complex_object)
{
const char* id = get_info(complex_object);
auto iter = my_funcs.find(id);
if (iter == my_funcs.end())
throw std::runtime_error("unknown object type");
return iter->second(complex_object);
}
int main()
{
std::cout << my_disp_fun(my_type{12345}) << std::endl;
std::cout << my_disp_fun(my_type{123.45}) << std::endl;
std::cout << my_disp_fun(my_type{std::string("hi")}) << std::endl;
return 0;
}