Home > OS >  How to manage various types of functions as containers
How to manage various types of functions as containers

Time:12-08

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();
    }
}
  • Related