C++ Functions with lambdas as arguments - c++

I have an overload function, with the following signatures:
void Foo(const std::function<void(int )> &func);
void Foo(const std::function<void(int, int)> &func);
And when I want to use Foo() with lambdas, I'll have to do something like this:
Foo((std::function<void(int )>) [] (int i ) { /* do something */ });
Foo((std::function<void(int, int)>) [] (int i, int j) { /* do something */ });
Both of which are not so user-friendly. It'd be a lot easier to use the function without having to add the casting "(std::function<...>)" before the lambdas - like this:
Foo([] (int i ) { /* do something */ }); // executes the 1st Foo()
Foo([] (int i, int j) { /* do something */ }); // executes the 2nd Foo()
So, I need another overload, that accept lambda as its argument, and which automatically casts the lambda to one of the above signatures. How can this be done? Or, is it possible in the first place?
template <typename Function> void Foo(Function function) {
// insert code here: should be something like
// - check the signature of the 'function'; and
// - call 'Foo()' corresponding to the signature
}
Please help.
PS. I'm using VS2010.

If your lambda does not capture any variables—that is, it begins with []—then it is convertible to a function pointer, and you can declare Foo like so:
void Foo(void(*func)(int));
void Foo(void(*func)(int, int));
If you want to keep the std::function versions, you can have these versions forward to that one. If you don’t want to implement them separately, I think a variadic template would do nicely:
template<class... Args>
void Foo(void(*func)(Args...)) {
return std::function<void(Args...)>(func);
}
If your lambdas capture variables, then they’re not convertible to function pointers, and you’ll need to wrap them in std::function yourself.

Lambda's convert to std::function<> implicitly, there's no explicit conversion needed.
std::function<void(int, int)> func = [](int a, int b){ printf("Hello Lambda world!"); };
func(1, 2);
Ah, you're trying to get a const reference to it. Why though? You should be better off with a right-hand reference (as it's a temporary) or a copy. In both of those cases it should implicitly convert as well...

Related

How to declare the template argument for an overloaded function

I have a fairly big project that, regarding this question,
I can summarize with
this structure:
void do_something()
{
//...
}
template<typename F> void use_funct(F funct)
{
// ...
funct();
}
int main()
{
// ...
use_funct(do_something);
}
All is working ok until someone (me) decides to reformat a little
minimizing some functions, rewriting
as this minimum reproducible example:
void do_something(const int a, const int b)
{
//...
}
void do_something()
{
//...
do_something(1,2);
}
template<typename F> void use_funct(F funct)
{
// ...
funct();
}
int main()
{
// ...
use_funct(do_something);
}
And now the code doesn't compile with
error: no matching function for call
where use_funct is instantiated.
Since the error message was not so clear to me
and the changes were a lot I wasted a considerable
amount of time to understand that the compiler
couldn't deduce the template parameter
because do_something could now refer to
any of the overloaded functions.
I removed the ambiguity changing the function name,
but I wonder if there's the possibility to avoid
this error in the future not relying on template
argument deduction.
How could I specify in this case the template argument for do_something(), possibly without referring to a function pointer?
I haven't the slightest idea to express explicitly:
use_funct<-the-one-with-no-arguments->(do_something);
You can wrap the function in a lambda, or pass a function pointer after casting it to the type of the overload you want to call or explicitly specify the template parameter:
use_funct([](){ do_something (); });
use_funct(static_cast<void(*)()>(do_something));
use_funct<void()>(do_something);
Wrapping it in a lambda has the advantage, that it is possible to defer overload resolution to use_func. For example:
void do_something(int) {}
void do_something(double) {}
template<typename F> void use_funct(F funct) {
funct(1); // calls do_something(int)
funct(1.0); // calls do_something(double)
}
int main() {
use_funct([](auto x){ do_something (x); });
}
[...] possibly without referring to a function pointer?
I am not sure what you mean or why you want to avoid that. void() is the type of the function, not a function pointer. If you care about spelling out the type, you can use an alias:
using func_type = void();
use_funct<func_type>(do_something);

Single-Expression Member Function Pointers

The standard way to represent a pointer to a member function for a specific instance of a class is to use a pointer to the instance and a pointer to the member function:
void Execute(Foo* inst, void (Foo::*func)(int), int x) {
(inst->*func)(x);
}
...
Execute(foo, &Foo::Bar, 42);
Is there any way to define Execute such that the function pointer is represented as a single expression?
For example:
void Execute(SomeType v, int x) {
(v.inst->*v.func)(x);
}
...
Execute(foo->Bar, 42);
My main problem is that in my specific case, Foo is nested under a long and unstable chain of namespaces, so an actual invocation using the standard syntax looks more like Execute(foo, &hello::darkness::my::old::friend::Foo::Bar, 42). I almost always have a local foo instance however, from which I can refer to the much simpler foo->Bar(42). I need to do some extra bookkeeping though, which is why I need to wrap the call in something like Execute. using directives and namespace aliases are not an option unfortunately.
Is there any way to define Execute such that the function pointer is represented as a single expression?
Yes. Change the function to use std::function or a callable template parameter, eg:
#include <functional>
void Execute(std::function<void(int)> v, int x)
{
v(x);
}
template<typename Callable>
void Execute(Callable v, int x)
{
v(x);
}
And then you can use std::bind() or a lambda for the input expression, eg:
#include <functional>
using namespace std::placeholders;
using FooType = std::remove_reference<decltype(*foo)>::type;
Execute(std::bind(&FooType::Bar, foo, _1), 42);
// or, in C++20 and later:
Execute(std::bind_front(&FooType::Bar, foo), 42);
Execute([=](int x){ foo->Bar(x); }, 42);
Also, just to mention that in C++Builder specifically, there is a __closure extension that allows calling member methods without having to qualify the class type at all, eg:
typedef void (__closure *TExecuteCallable)(int);
void Execute(TExecuteCallable v, int x)
{
v(x);
}
...
Execute(foo->Bar, 42);
// or
Execute(&(foo->Bar), 42);

Passing a function with arguments as an argument in C++ (Arduino)

I'd like to write a sort-of wrapper function for my class... And i really dont know how to do that!
See, i want a, say, run(), function, to accept a function as an argument, thats the easy part.
The usage would be something like
void f() { }
void run(int (*func)) {
//whatever code
func();
//whatever code
}
run(f);
That should just run the f() function, right?
But what if f() had required arguments? Say it was declared as f(int i, int j), i would go along rewriting the run() function to separately accept those ints, and pass them to the f() function.
But I'd like to be able to pass Any function to run(), no matter how many arguments, or what type they are. Meaning, in the end, i'd like to get usage similar to what i would expect the hypothetical
void f() {int i, int j}
void v() {char* a, int size, int position}
void run(int (*func)) {
//whatever code
func();
//whatever code
}
run(f(1, 2));
run(v(array, 1, 2));
to do. I know it looks dumb, but i think i'm getting my point across.
How would i do that?
Please remember that this is arduino-c++, so it might lack some stuff, but i do believe there are libraries that could make up for that...
If you have access to std::function then you can just use that:
void run(std::function<void()> fn) {
// Use fn() to call the proxied function:
fn();
}
You can invoke this function with a lambda:
run([]() { f(1, 2); });
Lambdas can even capture values from their enclosing scope:
int a = 1;
int b = 2;
run([a, b]() { f(a, b); });
If you don't have std::function but you can use lambdas, you could make run a template function:
template <typename T>
void run(T const & fn) {
fn();
}

How to wrap a function with a varying number of default arguments to have only one argument?

I have a template function, let's call it the "client":
template<typename T>
void client(T (*func)(const std::string&), const std::string& s) {}
Then there are a number of "adaptee" functions that all have an identical type of the first, non-default argument, but the following arguments vary in number and have default values:
void adaptee_one(const std::string&, int i = 1, char* c = nullptr) {}
void adaptee_two(const std::string&, float* f = nullptr) {}
The above functions are a given. Now what I want to do is to pass them to the above client<>() function as the first parameter, and I only care about passing the first argument, const std::string&. So I do the following:
void bindAdapteeOne(const std::string& s) {
return adaptee_one(s);
}
void bindAdapteeTwo(const std::string& s) {
return adaptee_two(s);
}
And then pass bindAdapteeX() to client<>().
What I'd like to do is to automate the wrapping or have one (templated) wrapper instead of one per adaptee. I feel this might be the case for variadics, but have little idea about how to apply them exactly.
C++11 is fine, C++14 is fine if absolutely necessary.
C++11 is fine, C++14 is fine if absolutely necessary.
C++11 solution here.
What I'd like to do is to automate the wrapping or have one (templated) wrapper instead of one per adaptee.
I wouldn't do that. You can simply use non-capturing lambdas and let them decay to function pointers:
client (+[](const std::string& s) { return adaptee_one(s); }, "foo");
I don't think that wrapping them in template stuff or whatever would give you a solution that is more readable or easy to use.
As a minimal, working example:
#include<string>
template<typename T>
void client(T (*func)(const std::string&), const std::string& s) {}
void adaptee_one(const std::string&, int i = 1, char* c = nullptr) {}
void adaptee_two(const std::string&, float* f = nullptr) {}
int main() {
client (+[](const std::string& s) { return adaptee_one(s); }, "foo");
}
This is one of those times where a macro helps:
#define WRAP_FN(f) +[](std::string const& s) -> decltype(auto) { return f(s); }
Though you could just write the body of that inline instead.
There isn't anything else you could do. The problem is that the default arguments aren't visible in the function's signature, so once you get into the type system, there's no way to differentiate:
void works(std::string const&, int=0);
void fails(std::string const&, int );
Both of those are void(*)(std::string const&, int). So you can't have a function template or class template wrapper - you need to do it inline with a lambda (or a macro that wraps a lambda).
I'm thinking I would create a class that wraps your parameters and have the client accept an instance of that class. That way, you only have one parameter, which contains however many parameters you so desire.
That parameter wrapper would provide the default values as well, and allow you to refine them in derived classes for specific purposes.
This is probably a little more self-documenting as well when compared to lambdas.
And who knows, when its time to read and write the parameters from a file, then the wrapper class would be the perfect place to do it.

How to curry a method on an object for passing it as a C-style callback?

Let's assume we have the following class A:
class A
{
public:
void sum(int x);
};
And we have a function f, which gets a C-style callback with one parameter of type int and calls it:
typedef void (*Callback)(int);
void f(Callback cb)
{
cb(5);
}
Is there any way in C++ to curry a method A::print on an object of type A and pass it to the function f? Something like this:
void main()
{
A a;
auto curry_a = ??; // something like curry_a = [&](int x) { a.sum(x) };
f(curry_a);
}
std::bind and lambda-function are not a solution, because they create objects of type std::function<> with overloaded operator(). It looks like currying in C++, but it cannot be used in my case. I need a real function pointer, i.e. generate code in real time.
You are out of luck, it can't be done in a satisfactory way: The only thing that is exactly a C-compatible function pointer is a function (or class-function but not instance function).
So, you'd have to create a function that fixes a parameter, like the this of a member function. The only way to set this parameter is through a global variable:
A *instance;
void (A::*a_fun)(int);
void applicator(int arg) { instance->*a_fun(arg); }
//...
int main() {
A a;
instance = &a;
a_fun = &A::sum;
f(applicator);
// ...
That is the only way to provide context to a plain function, through global variables.