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
.
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)...)())
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With