C++ need a container to store user defined function

≡放荡痞女 提交于 2020-01-15 10:59:29

问题


I am trying to create a interface between user defined function and data. Let's say I need to create a function called MapFun(), input of MapFun() includes user defined function (UDF) handle and UDF inputs.

void userFun1(Data data, int in1, int in2){
    // user defined function 1;
}

void userFun2(Data data, int in1, int in2, std::string s){
    // user defined function 2;
}

// ...
// apply user function 1 on data
MapFun(@userFun1, data, 3, 4);
// apply user function 2 on data
MapFun(@userFun2, data, 1, 2, "algorithm");

User will write userFun and apply it with MapFun(). So, how to design MapFun()? User function may have different inputs and the signature can't be predicted. In addition, MapFun() won't evaluate userFun immediately, instead, it stores all userFun and do a lazy evaluation.

Any suggestions are greatly appreciated.


回答1:


User function may have different inputs and the signature can't be predicted.

It seems a typical works for variadic templates

In addition, MapFun() won't evaluate userFun immediately, instead, it stores all userFun and do a lazy evaluation.

Not sure to understand but I suppose you can obtain what do you want using std::bind() or, maybe better, with lambda functions.

I propose the following C++14 variadic template MapFun() function that return a lambda function that capture both user-function and argument. That function can be executed later.

template <typename F, typename ... Args>
auto MapFun (F const & f, Args const & ... args)
 { return [=]{ f(args...); }; }

The following is a full working example

#include <iostream>

template <typename F, typename ... Args>
auto MapFun (F const & f, Args const & ... args)
 { return [=]{ f(args...); }; }

void userFun1 (int i1, int i2)
 { std::cout << "uf1, " << i1 << ", " << i2 << std::endl; }

void userFun2 (int i1, int i2, std::string const & s)
 { std::cout << "uf2, " << i1 << ", " << i2 << ", " << s << std::endl; }

int main ()
 {
   auto l1 = MapFun(userFun1, 1, 2);
   auto l2 = MapFun(userFun2, 3, 4, "five");

   l2();
   l1();
 }



回答2:


If I understand right, you just want to store a function and a set of arguments so that they can be called later. This is exactly what std::bind does (anyway, the simplest thing it does). In fact, you could possibly just use std::bind directly in place of your MapFun:

auto func1 = std::bind(userFun1, data, 3, 4);
auto func2 = std::bind(userFun2, data, 1, 2, "algorithm");
// ... and later,
func1();
func2();

Note the auto in those: you can't (portably) write the type of any object returned by std::bind, and those two example objects will have different types. But both of those would implicitly convert to the common type std::function<void()>. You can store a bunch of std::function<void()> objects in nearly any container type you want, to be used later:

std::map<unsigned int, std::function<void()>> func_map;
func_map[0] = std::bind(userFun1, data, 3, 4);
func_map[1] = std::bind(userFun2, data, 1, 2, "algorithm");
// ...
auto func_iter = func_map.find(key);
if (func_iter != func_map.end() && func_iter->second) {
    (func_iter->second)();
}

Of course, if you want to use your name of the function, and/or if you need the explicit common return type to work well with other templates or something, you can just wrap std::bind:

template <class F, class... Args>
std::function<void()> MapFun(F&& f, Args&&... args) {
    return std::bind<void>(std::forward<F>(f), std::forward<Args>(args)...);
}

Or if your MapFun is supposed to store the callable object inside some class member container or something, not just create and return one (it's not clear), it can of course do that by using std::bind and then adding the result to whatever container you need.




回答3:


If you only need to backport std::invoke from C++17, well, its simplest form is quite straightforward:

template<class F, class... Args> decltype(auto) invoke(F &&f, Args &&...args) {
    return ::std::forward<F>(f)(::std::forward<Args>(args)...);
}


来源:https://stackoverflow.com/questions/53272335/c-need-a-container-to-store-user-defined-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!