[Development] [Interest] Qt 5 connect to static function: Suggestion for new overload.
Thiago Macieira
thiago.macieira at intel.com
Sat May 4 18:01:35 CEST 2013
On sábado, 4 de maio de 2013 10.45.14, Olivier Goffart wrote:
> I would say this is an instance of the XY problem:
> http://meta.stackoverflow.com/questions/66377/what-is-the-xy-problem
>
> Why would you want to have a 'receiver' when there is no really a receiver?
So that the connection is broken if the receiver is deleted.
E.g.:
connect(sender, &Sender::signal, receiver, &Receiver::foo);
The above will disconnect if the receiver is deleted, but it can only be used
if the arguments match. If they don't, you have to write something like:
connect(sender, &Sender::signal, [receiver]() { receiver->foo(1); });
which does not delete when the receiver goes away, so it could be dangerous.
was easier.
Then there's one more case. I spent half an hour debugging why the following
does not compile:
connect(sender, &Sender::signal, qApp, &QCoreApplication::quit);
Without reading the next lines after the break, can you guess why that's the
case?
I was bitten twice in the past two days writing code using the new syntax. The
first was the above: a static slot. The second was because QProcess::finished
has an overload.
https://codereview.qt-project.org/55365
> Appart from being the object which owns the member function, the QObject
> receiver also get used for those features:
> - The connection is automatically disconnected when the receiver is
> destroyed.
> - The thread affinity of the object is used to possibly perform a queued
> connection in the thread of the receiver
> - The receiver's sender() and senderSignalIndex() are updated.
>
> Those features are totally valid use case you may want for lambda functions,
> and I agree we should support that. I had that in mind with several ways
> to solve it, but it was not implemented in Qt 5.0 because i left that for
> later.
>
> Here are some way to solve it:
>
> 1) add new overloads of QObject::connect with 5 arguments that takes functor
> as parametters with a receiver.
>
> Code would look like this:
> connect(obj1, &Foo::theSignal, obj2, [&]() { obj3->doSomething(obj2); });
>
> This is easy to do with C++11 variadic template, a bit more difficult if
> you only have decltype and C++11 revisited SFINAE, and even more difficult
> if you can't use C++11 at all.
We write it for the fully-featured compiler, then we figure out what to do for
older compilers. If it can be easily done for older compilers, great! If it
can't, too bad -- anyone using those older compilers isn't using the feature
anyway, so they won't miss it.
> 2) Since we now return a QObject::Connection, we can add API on that class.
> For example:
>
> auto c = connect(obj1, &Foo::theSignal, [&]() { obj3->doSomething(obj2);
> }); c.addDeleteWatcher(obj2);
> c.addDeleteWatcher(obj3);
> c.queueInThread(obj2.thread());
Good, let's do it.
> Implementation of this would be trivial.
>
> Other syntaxes are possible:
> connect(obj, ..., [&]() { ... } ).setReceiver(obj2);
>
> The challenge is thread safety. (what if the signal is emitted in another
> thread before we set the receiver?)
Another syntax:
connect(obj1, &Foo::theSignal, { obj2, obj3 }, [=](){ obj3->doSomething(); });
> 3) for deletion purpose, maybe having a kind of scoped pointer around
> QObject::Connection
>
> obj2->m_connections.track(connect(obj1, ..., [] {...} ));
>
> it could also be an API in QObject itself
> obj2->trackConnection(connect(obj1, ..., [] {...} ));
I didn't understand this one. Are you doing the equivalent of connecting
obj2's destroyed() to the connection's delete (now)?
> I'm tempted to say that the new QObject::connect overloads are not that bad
> after all.
Except the convenience.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20130504/098f9b14/attachment.sig>
More information about the Development
mailing list