Syntax sugar for signal slot - c++

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);

Related

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.

Questions about using a per-function-struct (parameter object) to emulate "named arguments" for options to function calls?

To improve code readability for options passed as arguments to a function I'm using a per-function-struct (parameter object) to emulate "named arguments" at the function invocation. The option values, members of the struct, typically have default values, so that at
function invocation not all options need to be specified. See the example code below for illustration.
I'm thinking of using this approach more widely for function invocations because the code seems quite compact while still readable when used with an initializer list without giving the type of the parameter object. Another advantage is that the implementation of the invoked function is straight forward/simple. However, I wonder:
Does this approach (pattern, idiom) have a name?
Can someone confirm this approach is portable? (It compiles with the
gcc- and clang-versions I use, but is it guaranteed by the
standard?)
Can someone confirm it requires C++14 and not just C++11?
Should I watch out for reduced execution speed or
increase memory useage? Or will the compilers be able to
efficiently optimize this? Note: In my current use cases these aspects are not a
factor, but I wonder if they might be a reason to avoid this as a
general approach.
[optional] One drawback with the approach is that it requires me to create and name an extra struct,
SetupOptions in the example. If I use a convention of naming the
type of the parameter object as <function-name>Options I'll sometimes get
rather long function declarations. Any suggestions for how to work
around this? A naming convention? Or can the "named arguments" be
emulated in a better way while still keeping the implementation
relatively simple?
[optional] Do we expect a future C++1z or later to provide better approaches
for named function parameters? (I know of N4172 but not it's status)
[optional] One example of a potential drawback with this approach is that the
user might forget to change all the options.
Do you see other drawbacks or caveats to be careful about?
Example code
The example below is based on an actual use case where I setup a
simulator / simulated environment.
/// #file Simulator.h
/// Simulator for interaction with HW devices. Used e.g. by test cases.
namespace Simulator {
struct SetupOptions {
bool faster_than_real_time = false;
double time_step = 0.01; // [s]
};
void setup(SetupOptions options) {
if (options.faster_than_real_time) {
// ...
}
// ...
}
} // namespace Simulator
/// ----------------------------------------------------------------------
/// #file use_simulator.cpp
void setup_simulator_for_application() {
Simulator::setup({}); // (1) Uses default setup
// ...
}
void setup_simulator_for_test_case() {
// (2) Use named struct member for readability
Simulator::setup({.faster_than_real_time = true});
// ..
}
Some relevant links:
https://marcoarena.wordpress.com/2014/12/16/bring-named-parameters-in-modern-cpp/ - the approach discussied in this SO question might correspond to a subset of the "Named Parameter Idiom" in the link.
N4172 - Proposal for named arguments.
Can someone confirm it requires C++14 and not just C++11?
None of them. It requires C99/C11 designated initializers. Which are not part of any version of C++.
So what you're writing isn't standard C++ at all. It's based on compilers permitting C11 code in C++.
Do we expect a future C++1z or later to provide better approaches for named function parameters?
The closest you're likely to get in the forseeable future is for something like this paper (PDF) to get standardized in C++20. That provides C++ support for designated initializers, but even then, it won't be compatible with C99/11's designated initializers.
So if you continue with this hybrid C11/C++11 syntax, it may become illegal.

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);

C++11 Lambda Expressions as Callback Functions

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.

What are the benefits of using Boost.Phoenix?

I can not understand what the real benefits of using Boost.Phoenix.
When I use it with Boost.Spirit grammars, it's really useful:
double_[ boost::phoenix::push_back( boost::phoenix::ref( v ), _1 ) ]
When I use it for lambda functions, it's also useful and elegant:
boost::range::for_each( my_string, if_ ( '\\' == arg1 ) [ arg1 = '/' ] );
But what are the benefits of everything else in this library? The documentation says: "Functors everywhere". I don't understand what is the good of it?
I'll point you out what is the critical difference between Boost.Lambda and Boost.Phoenix:
Boost.Phoenix supports (statically) polymorphic functors, while Boost.Lambda binds are always monomorphic.
(At the same time, in many aspects the two libraries can be combined, so they are not exclusive choices.)
Let me illustrate (Warning: Code not tested.):
Phoenix
In Phoenix a functor can converted into a Phoenix "lazy function" (from http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html)
struct is_odd_impl{
typedef bool result_type; // less necessary in C++11
template <typename Arg>
bool operator()(Arg arg1) const{
return arg1 % 2 == 1;
}
};
boost::phoenix::function<is_odd_impl> is_odd;
is_odd is truly polymorphic (as the functor is_odd_impl). That is is_odd(_1) can act on anything (that makes sense). For example in is_odd(_1)(2u)==true and is_odd(_1)(2l)==true. is_odd can be combined into a more complex expression without losing its polymorphic behavior.
Lambda attempt
What is the closest we can get to this in Boost.Lambda?, we could defined two overloads:
bool is_odd_overload(unsigned arg1){return arg1 % 2 == 1;}
bool is_odd_overload(long arg1){return arg1 % 2 == 1;}
but to create a Lambda "lazy function" we will have to choose one of the two:
using boost::lambda::bind;
auto f0 = bind(&is_odd_overload, _1); // not ok, cannot resolve what of the two.
auto f1 = bind(static_cast<bool(*)(unsigned)>(&is_odd_overload), _1); //ok, but choice has been made
auto f2 = bind(static_cast<bool(*)(long)>(&is_odd_overload), _1); //ok, but choice has been made
Even if we define a template version
template<class T>
bool is_odd_template(T arg1){return arg1 % 2 == 1;}
we will have to bind to a particular instance of the template function, for example
auto f3 = bind(&is_odd_template<unsigned>, _1); // not tested
Neither f1 nor f2 nor f3 are truly polymorphic since a choice has been made at the time of binding.
(Note1: this may not be the best example since things may seem to work due to implicit conversions from unsigned to long, but that is another matter.)
To summarize, given a polymorphic function/functor Lambda cannot bind to the polymorphic function (as far as I know), while Phoenix can. It is true that Phoenix relies on the "Result Of protocol" http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of but 1) at least it is possible, 2) This is less of a problem in C++11, where return types are very easy to deduce and it can be done automatically.
In fact, in C++11, Phoenix lambdas are still more powerful than C++11
built-in lambdas. Even in C++14, where template generic lambdas are
implemented, Phoenix is still more general, because it allows a
certain level of introspection. (For this an other things, Joel de
Guzman (developer of Phoenix) was and still is well ahead of his
time.)
Well, its a very powerful lambda language.
I used it to create a prototype for a math-like DSL:
http://code.google.com/p/asadchev/source/browse/trunk/work/cxx/interval.hpp
and many other things:
http://code.google.com/p/asadchev/source/browse/#svn%2Ftrunk%2Fprojects%2Fboost%2Fphoenix
I have never used Phoenix, but...
From the Phoenix Library docs:
The Phoenix library enables FP techniques such as higher order functions, lambda (unnamed functions), currying (partial function application) and lazy evaluation in C++
From the Wikipedia article on Functional programming:
... functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state
So, Phoenix is a library for enabling Functional Programming in C++.
The major interest in Functional Programming these days seems to stem from the perceived advantages in correctness, and performance, due to limiting or eliminating side-effects.
Correctness, because without side-effects, the code that you see is everything going on in the system. Some other code won't be changing your state underneath you. You can much more easily write bug-free code in this sort of environment.
Performance, because without side-effects, the code you write can safely run in parallel, without any resource managing primitives, or atomic-access tricks. Multi-threading can be enabled extremely easily, even automatically, and operate extremely efficiently.
Don't look at Boost.Phoenix2.
Evolution of lambda expressions in boost looks like:
Bind -> Lambda, Phoenix2 (as Spirit part) -> Phoenix3 (as separate library, under development).
Result is single lambda-library with polymorphic functors support (others are going to become deprecated).
Functional programming in C++. It's hard to explain unless you have previously used a language with proper support for functional programming, such as SML. I tried to use Phoenix and found it nice, but very impractical in real-life projects because it greatly increases compilation times, and error messages are awful when you do something wrong. I rememeber getting a few megabytes of errors from GCC when I played with Phoenix. Also, debugging deeply nested template instantiations is a PITA. (Actually, these are also all the arguments against using most of boost.)