Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ universal function caller

Tags:

c++

c++11

I'd want to implement a function caller that works just like the thread constructor. For example

std::thread second (bar,0);

will start a thread which calls bar with the single argument 0. I would like to do the same thing, but I do not know how.

For example, given:

void myFunc(int a){
    cout << a << endl;
}

I would like:

int main() {
    caller(myFunc,12);
}

to call myFunc with the parameter 12.

like image 654
Maxian Nicu Avatar asked Apr 28 '15 12:04

Maxian Nicu


2 Answers

std::bind will make a callable object from any callable object with an arbitrary set of parameters, just as the thread constructor does. So just wrap that in a function that calls it:

template <typename... Args>
auto caller(Args &&... args) {
    return std::bind(std::forward<Args>(args)...)();
}

Note that the auto return type requires C++14 or later. For C++11, you'll have to either return void, or specify the type:

auto caller(Args &&... args) 
    -> decltype(std::bind(std::forward<Args>(args)...)())
like image 93
Mike Seymour Avatar answered Oct 07 '22 09:10

Mike Seymour


If all you want to do is call an arbitrary function with an arbitrary argument, that's just a template on both types:

template <typename Function, typename Arg>
void call_with_one(Function&& f, Arg&& arg) {
    f(std::forward<Arg>(arg));
}

which you can expand to call with any number of args by making it variadic:

template <typename Function, typename... Arg>
void call_with_any(Function f, Arg&&... args) {
    f(std::forward<Arg>(args)...);
}

Or really f should be a forwarding reference as well:

template <typename Function, typename... Arg>
void call_with_any(Function&& f, Arg&&... args) {
    std::forward<Function>(f)(std::forward<Arg>(args)...);
}

Note that this will only work with functions and objects that implement operator(). If f is a pointer-to-member, this will fail - you will have to instead use std::bind as Mike Seymour suggests.

like image 35
Barry Avatar answered Oct 07 '22 07:10

Barry