C++11 Lambda Expressions as Callback Functions - c++

Does any C++ GUI toolkit out there support definition of callback functions as C++11 lambda expressions? I believe this is a unique pro of using C# (compared to C++ at least) for writing GUI-based programs. What type signature should I use for functions taking lambda expressions as arguments and how does these support implicit conversions?

The answer to second part of the question: You could use std::function<Signature> where Signature = e.g. void (int) or - if the lambdas don't take closures - the good old void (Foo*)(int) method, since a lambda without a closure must be convertible to proper function type. So, for example a call to a method with signature:
void AddHandler(std::function<void (int)> const &);
could look like this:
myObject.AddHandler([&](int _) {
// do something and access captured variables by reference
});

Does any C++ GUI toolkit out there support definition of callback functions as C++11 lambda expressions?
If they accept function pointers then you can at least use lambdas that don't capture anything. Such lambdas can be automatically converted to function pointers.
What type signature should I use for functions taking lambda expressions as arguments and how does these support implicit conversions?
If you want people to use lambdas or any callable object then you could either have your API accept std::function objects, or use a template:
template<typename Callback>
void do_it(Callback c) {
c();
}
do_it([&]{ c = a+b; });
A template will allow the lambda to be inlined while std::function require indirection. This may not matter much for GUI callbacks.

There is a new GUI toolkit that meets your requirement. It is trying to provide many features for improving development efficiency.
An introduction to the library.
http://nanaproject.wordpress.com/2011/12/16/preliminary-study-of-nana-c-library/
An article to explain how to reduce complexity by using the library and std::bind together.
http://nanaproject.wordpress.com/2012/01/31/idioms-and-insights-for-a-good-design/
Have fun!

With C++11 templatious library it doesn't matter whether GUI supports lambdas. You can make GUI to do whatever you want with messages and keep the same code at domain logic side. Check out this article about taming Qt and these examples.

Related

What is the advantage of using boost::bind?

The definition and application of boost::bind are clearly outlined in the boost website, yet I hardly could find what is the benefit of using it over using a normal function call? Or to put it simply in which scenarios it might come in handy?
Sometimes you have a set of arguments that you are going to pass to the function, but you wish to call the function later without needing to pass the arguments that are already known. One reason to need this may be because the call may need to conform to an interface that doesn't allow those arguments. This is typical in the (functor style) "callback" idiom.
That situation can be solved by defining a class that stores the arguments as members, and defines function call operator overload that delegates to the original function and passes the arguments stored as members.
boost::bind is a structured way to represent such "argument binding" without needing to define the class yourself. The standard library used to have std::bind1st and std::bind2nd which were more limited, less generic forms of bind.
boost::bind is rarely needed anymore since it was introduced to the standard library as std::bind in C++11, and furthermore lambdas were introduced in C++11 and improved in C++14 and they have largely obsoleted bind.
bind provides a way to take a function or a function object with a certain arity and transform it to another function with lesser arity by precisely binding one or more arguments. And you can do it in place.
bind and functions don't have a good comparison.
bind is more comparable to simple lambdas that call a function and fix certain parameters in their implementation.
The big difference between boost::bind and a modern lambda is that the bind object has a certain degree of instrospection associated with it that the lambda doesn't have.
For example you could in principle recover the original function and reconstruct what is the argument bound.
In a lambda everything is private, even the simplest implementation.
In other words, the result of boost::bind is an "expression" and the type has well defined pattern (e.g. boost::bind_t<...> or something, and that can be matched in a template function argument).
Lambdas instead are each their own unknowable sui generis type.
Admittedly, few people maybe interested in the difference, but it is there and I played with it once or twice to implement a symbolic system (for derivatives).
I can't say the same about std::bind because the object returned is unspecified by the standard and it could be more difficult to reconstruct the full bind "expression".

Any reason not to use global lambdas?

We had a function that used a non-capturing lambda internal to itself, e.g.:
void foo() {
auto bar = [](int a, int b){ return a + b; }
// code using bar(x,y) a bunch of times
}
Now the functionality implemented by the lambda became needed elsewhere, so I am going to lift the lambda out of foo() into the global/namespace scope. I can either leave it as a lambda, making it a copy-paste option, or change it to a proper function:
auto bar = [](int a, int b){ return a + b; } // option 1
int bar(int a, int b){ return a + b; } // option 2
void foo() {
// code using bar(x,y) a bunch of times
}
Changing it to a proper function is trivial, but it made me wonder if there is some reason not to leave it as a lambda? Is there any reason not to just use lambdas everywhere instead of "regular" global functions?
There's one very important reason not to use global lambdas: because it's not normal.
C++'s regular function syntax has been around since the days of C. Programmers have known for decades what said syntax means and how they work (though admittedly that whole function-to-pointer decay thing sometimes bites even seasoned programmers). If a C++ programmer of any skill level beyond "utter newbie" sees a function definition, they know what they're getting.
A global lambda is a different beast altogether. It has different behavior from a regular function. Lambdas are objects, while functions are not. They have a type, but that type is distinct from the type of their function. And so forth.
So now, you've raised the bar in communicating with other programmers. A C++ programmer needs to understand lambdas if they're going to understand what this function is doing. And yes, this is 2019, so a decent C++ programmer should have an idea what a lambda looks like. But it is still a higher bar.
And even if they understand it, the question on that programmer's mind will be... why did the writer of this code write it that way? And if you don't have a good answer for that question (for example, because you explicitly want to forbid overloading and ADL, as in Ranges customization points), then you should use the common mechanism.
Prefer expected solutions to novel ones where appropriate. Use the least complicated method of getting your point across.
I can think of a few reasons you'd want to avoid global lambdas as drop-in replacements for regular functions:
regular functions can be overloaded; lambdas cannot (there are techniques to simulate this, however)
Despite the fact that they are function-like, even a non-capturing lambda like this will occupy memory (generally 1 byte for non-capturing).
as pointed out in the comments, modern compilers will optimize this storage away under the as-if rule
"Why shouldn't I use lambdas to replace stateful functors (classes)?"
classes simply have fewer restrictions than lambdas and should therefore be the first thing you reach for
(public/private data, overloading, helper methods, etc.)
if the lambda has state, then it is all the more difficult to reason about when it becomes global.
We should prefer to create an instance of a class at the narrowest possible scope
it's already difficult to convert a non-capturing lambda into a function pointer, and it is impossible for a lambda that specifies anything in its capture.
classes give us a straightforward way to create function pointers, and they're also what many programmers are more comfortable with
Lambdas with any capture cannot be default-constructed (in C++20. Previously there was no default constructor in any case)
Is there any reason not to just use lambdas everywhere instead of "regular" global functions?
A problem of a certain level of complexity requires a solution of at least the same complexity. But if there is a less complex solution for the same problem, then there is really no justification for using the more complex one. Why introduce complexity you don't need?
Between a lambda and a function, a function is simply the less complex kind of entity of the two. You don't have to justify not using a lambda. You have to justify using one. A lambda expression introduces a closure type, which is an unnamed class type with all the usual special member functions, a function call operator, and, in this case, an implicit conversion operator to function pointer, and creates an object of that type. Copy-initializing a global variable from a lambda expression simply does a lot more than just defining a function. It defines a class type with six implicitly-declared functions, defines two more operator functions, and creates an object. The compiler has to do a lot more. If you don't need any of the features of a lambda, then don't use a lambda…
After asking, I thought of a reason to not do this: Since these are variables, they are prone to Static Initialization Order Fiasco (https://isocpp.org/wiki/faq/ctors#static-init-order), which could cause bugs down the line.
if there is some reason not to leave it as a lambda? Is there any reason not to just use lambdas everywhere instead of "regular" global functions?
We used to use functions instead of global functor, so it breaks the coherency and the Principle of least astonishment.
The main differences are:
functions can be overloaded, whereas functors cannot.
functions can be found with ADL, not functors.
Lambdas are anonymous functions.
If you are using a named lambda, it means you are basically using a named anonymous function. To avoid this oxymoron, you might as well use a function.

Is it safe to pass C++11 std::function to a legacy function that takes boost::function

We have a legacy system that uses boost::function intensively, now it's decided to move to newer modern C++ standards. Suppose we have a legacy function like this:
void someFunction(boost::function<void(int)>);
Is it safe to directly pass in a C++11 function?
//calling site, new C++11 code
std::function<void(int)> func = [](int x){
//some implementation
}
someFunction(func); //will this always work?
Does boost::function also handles standard C++11 lambda gracefully?
// will this also work?
someFunction([](int x)->void{
//some implementation
});
Yes this will work.
The important thing is that you shouldn't confuse type safety with compatibility. You're not passing std::function as a boost::function. You're telling the compiler to wrap you std::function into a boost::function.
That might not be efficient - as each will add another layer of indirection on invocation. But it will work.
Same thing goes for lambdas: there's nothing magic about lambdas, it's just syntactic sugar for a function object.

C++: Creating a function object with mem_fn and bind1st

Disclaimer: This description contains a lot of Qt specific functionality. This is not necessary to answer the question, I'm just including it to explain the background.
I need to do some heavy computations in my QT application.
In order to do this, I would like to use QtConcurrent::run(myFunction) This is Qt's version of async and creates a future, which at some point will contain the result of myFunction.
The problem is that the function is both a member function and takes complex parameters.
I know that you can pass both a function and a pointer to QtConcurrent::run. The function will then be invoked on the pointer. You can even provide a list of parameters. But it seems like this list only accepts parameters such as int, double or QString.
Actual Question:
I would like to convert this line of code:
model->nextStep(simulatedResult->last().molecules, dt)
into
myFunction()
That means I need to
bind the pointer to the function
bind the arguments to the function
This is my code so far:
auto memfun=std::mem_fn(&ConcreteModel::nextStep);
auto memfun_bound_to_model=std::bind1st(memfun,model);
auto memfun_bound_result=std::bind1st(memfun_bound_to_model,simulatedResult->last().molecules);
auto memfun_bound_dt=std::bind1st(memfun_bound_result,dt);
Unfortunately this doesn't work.
There are 18 compiler errors, here is the pastebin: http://pastebin.com/2rBQgFNL
It would be great, if you could explain how to do this properly.
Not necessary for an answer, but even better, would be code for QtConcurrent::run.
Simply use a lambda expression.
auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }
You could also use std::bind (see #JonathanWakely's answer), but lamda expressions are imho more universal and powerful.
Also, keep in mind that reading and writing to the same memory from multiple threads will result in a data race (don't pass pointers/references to mutable data to the QT threads unless synchronization is used).
You're trying to mix the C++98 bind1st with the C++11 mem_fn, which isn't possible.
bind1st requires an adaptable binary function which means one that defines certain typedefs, and one that takes exactly two arguments. You can't use it with something that requires more than two and keep binding one argument at a time.
In C++11 it is possible to wrap function objects without those typedefs, thanks to decltype and other new features, so "adaptable binary function" is a useless concept now, and bind1st is useless and deprecated.
The solution is simply to use C++11 features instead of bind1st, e.g. std::bind or a lambda expression.
auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);

Syntax sugar for signal slot

Recently I searched internet for good signal-slot library and wonder why on Earth we need such a cumbersome syntax for connecting member methods to signals?
Usually we have to write something like this:
mySignal.connect(&MyClassName::myMethodName, this);
or like that:
mySignal += std::bind(&MyClassName::myMethodName, this, std::placeholders::_1);
There is obvious duplication and unnessesary typing. Is it possible in modern C++ to implement such functionality in, for example, C# way:
mySignal += myMethodName
and automatically capture pointer to member function and this pointer from context?
Is it possible in modern C++ to implement such functionality in, for example, C# way? [...]
No, that's not possible in C++. The syntax for taking the address of a member function requires qualifying the function name with the class name (i.e. &MyClassName::myMethodName).
If you don't want to specify the class name, one possibility is to use lambdas. In particular, if you can afford a C++14 compiler, generic lambdas allow writing:
mySignal.connect([this] (auto x) -> { myMethodName(x) });
Sadly, you can't get much terser than this. You can use default lambda capture to save some syntactic noise:
mySignal.connect([&] (auto x) -> { myMethodName(x) });
However, Scott Meyers warns against the pitfalls of default lambda capture modes in his new book Effective Modern C++. From the readability point of view, I'm not sure this improves things a lot compared to your first option.
Besides, things soon become awkward if you want your lambda to perfectly forward its argument(s) to myMethodName:
mySignal.connect([&] (auto&& x) -> { myMethodName(std::forward<decltype(x)>(x)) });
If you don't mind macros (I usually do), you can employ a preprocessor-based solution as suggested by Quentin in their answer. However, I would prefer using a perfect-forwarding lambda in that case:
#define SLOT(name) \
[this] (auto&&... args) { name (std::forward<decltype(args)>(args)...); }
Which you could use like so:
e.connect(SLOT(foo));
Here is a live demo on Coliru.
Shall the preprocessor have a shot at it ?
#include <type_traits>
#define CONNECT(method) \
connect(&std::remove_pointer_t<decltype(this)>::method, this)
Cane be used as follows :
mySignal.CONNECT(myMethodName);