Context
(C ++ 11) As part of the protection in the serialization code snippet, I want to check if the function pointer is known. (Otherwise, the deserialization mechanism will probably fail).
This is the (simplified) part of the code that illustrates the mechanism:
template <typename Fun>
struct FunctionCallRegistry
{
static std::unordered_map<Fun, std::string>& FunctionMap()
{
static std::unordered_map<Fun, std::string> map;
return map;
}
static void Register(Fun function, std::string name)
{
auto& map = FunctionMap();
auto it = map.find(function);
if (it == map.end())
{
map.insert(std::pair<Fun, std::string>(function, name));
}
}
static void Ensure(Fun function)
{
auto& map = FunctionMap();
auto it = map.find(function);
if (it == map.end())
{
throw std::exception("Function not found.");
}
}
};
struct FunctionCallRegistryInitializer
{
template <typename Ret, typename... Args>
explicit FunctionCallRegistryInitializer(Ret(*function)(Args...),
const char* name)
{
FunctionCallRegistry<Ret(*)(Args...)>::Register(function, name);
}
};
#define RegisterFunction(fcn) FunctionCallRegistryInitializer fcn_reg_##__COUNTER__(&fcn, #fcn);
Serialization is now easy, given that we can find a function and emit a name. Similarly, deserialization looks through the name and emits a factory function wrapped in a class (this is the easy part).
Registration works as follows: basically for each function I call Registerwith the function pointer and name (which is used to serialize (de)). There, a macro is involved here and several auxiliary classes to make plumbing. For instance:.
struct Testje
{
static int test(int lhs, int rhs) {
std::cout << lhs << " + " << rhs << std::endl;
return lhs + rhs;
}
};
RegisterFunction(Testje::test);
Fun - f.ex. void (*fcn)(int, int). , , , -. "", ...
MSV++, , , :
error C2338: The C++ Standard doesn't provide a hash for this type.
fcn , , , .
, - ; - , Fun . , name , , .
: ? , ?