[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