I am trying to manage function list through c template.
template<typename T, typename... Args>
std::map<std::wstring, std::function<T(Args...)>> mFuncs;
Above code is not the correct sentence, but like above code concept, I want to manage various types of functions as a List.
void RegisterFuncs()
{
mFuncs.emplace(L"Func1", [&]()->bool{ ... });
mFuncs.emplace(L"Func2", [&](int a, std::string b)->int{ ... });
mFuncs.emplace(L"Func3", [&](std::tuple<int,int>& a){ ... });
...
...
...
mFuncs.emplace(L"Func", [&](args...)->auto{ ... });
}
template<typename... TArgs>
inline auto CallFunc(const wchar_t* pKey, TArgs&&... pArgs)
{
...
...
return mFuncs[pKey](std::forward<TArgs>(pArgs)...);
}
How can I implement the above concept?
CodePudding user response:
use std::any
std::map<std::string, std::any> f;
int i = 3;
void RegisterFuncs()
{
f.emplace("func1", std::function<double(int)>([&](int k){i = k; return 5.0; }));
f.emplace("func2", std::function<bool()>([](){return false; }));
// ^^^^^^^^^^^^^^^^ cant use lambda type becuase any_cast doesnt support implicit casting
}
template<typename R, typename... Args>
inline R CallFunc(const std::string& name, Args&&... args)
{
return std::any_cast<std::function<R(Args...)>>(f[name])(args...);
}
int main()
{
RegisterFuncs();
double r = CallFunc<double, int>("func1", 6);
std::cout << "r: " << r << " i: " << i << "\n";
bool b = CallFunc<bool>("func2");
std::cout << std::boolalpha << "b: " << b << "\n";
//types must match exactly or bad_any_cast is thrown
try
{
int c = CallFunc<int>("func2");
std::cout << "c: " << c << "\n";
}
catch(std::bad_any_cast e)
{
std::cout << e.what();
}
}