[Development] [RFC] What to do about overloaded signals/slots?

Grégoire Barbier devel at g76r.eu
Mon Oct 7 16:49:18 CEST 2013


Le 07/10/2013 15:33, Olivier Goffart a écrit :
> On Monday 07 October 2013 12:52:48 Grégoire Barbier wrote:
>
>> Hi,
>>
>> I'm currently porting for the first time a Qt4 app to Qt5 and meanwhile
>> discovering new great Qt5 features, therefore I'm far from beeing an expert.
>>
>> However my current opinion about Qt5 new connect syntaxes is that the
>> one with functor is great¹ but the one with pointers to members, even
>> though being nicer to read since we all dislike using macros, is in fact
>> dangerous since not only hard to use (as you state many developers are
>> not at ease with finding which class to prefix with) but also hard to
>> maintain because e.g.
>> (i) code reingeniering (remember that slots are not only defined in Qt
>> framework classes but also in casual application code which is less
>> stable)
>
> I consider that as an advantage.  When you refactor the code, you get a
> compilation error instead of a runtime warning.

I agree that getting rid of runtime warning and being warned at compile 
time is better. Such as when calling an inexistant slot or a slot which 
has changed its signature.

However in the refactor case I think there are cases (I though moving a 
slot to a base class but you say I'm wrong) where there were no runtime 
warning but a still working connection after the refactoring.

>> such as moving a slot from a class to its parent would break
>> connections, and
>
> Moving a slot to the base class do not break.

Ok. Probably I don't remember well the issue I faced, maybe the 
contrary: moving a slot to child class.

>> (ii) slot overloading change in a parent class is undetectable and will
>> missconduct signals to undesired slot method.
>>
>> With macros these issues did not happen because meta object mechanisms
>> support them through the characters string signature, which even support
>> slots overloading in a convenient fashion (i.e. by preserving source
>> compatibility even when overloading a slot method).
>>
>> In addition, I find slot overloading usefull, more precisely I find
>> convenient to define a slot in a parent class on a virtual method and to
>> overload it in relevant child classes without worrying with slot anymore.
>> I say slot because you wanted to talk about slots but I do the same with
>> non-slot Q_INVOKABLE methods when handling multithread invocations
>> without signals or connections (through raw invokeMethod() calls).
>>
>> Finally, even though I find SIGNAL() and SLOT() macros not so beautifull
>> than pointers to members, frankly, QtCreator does the completion so well
>> and so painless that I forgot that there were macros in connect call
>> until I read Qt5 release notes...
>>
>> Therefore, if I were a Qt project developer, not only I would not
>> deprecate slot overloading, but if I were to choose between slot
>> overloading and pointers to members connect, I would deprecate pointers
>> to members connect.
>> However I'm not a Qt project developer. And I may be wrong.
>> And I know that calling for deprecating a brand new feature is somewhat
>> heretic. Please don't burn me alive.
>>
>> Regards.
>
>
> Using some c++11, I was able to make a macro that might make the syntax
> easier:
>
> template <typename Type, typename T> struct Helper;
> template <typename Type, typename... Args> struct Helper<Type, void(Args...)>
> {
>      template <typename Ret> static auto help(Ret (Type::*func)(Args...))
>                    -> decltype(func) { return func; }
>      template <typename Ret> static auto help(Ret (Type::*func)(Args...) const)
>                    -> decltype(func) { return func; }
> };
>
>
> #define GET_METHOD(OBJ, FUNC, ARGS) (OBJ),  [&](){ \
>    typedef std::remove_reference<decltype(*(OBJ))>::type Type; \
>    return Helper<Type, void ARGS>::help(&Type::FUNC); }() \
>
>
> To be used like this:
>
>   connect( GET_METHOD(process, error, (QProcess::ProcessError)) ,
> 		GET_METHOD(receiver, mySlot, ());
>
> It is quite similar to the old syntax but benefits from the adventage on the
> new one.  But it needs lambda and decltype,   and one yould need to
> reimplement it for each argument types

This sounds great :-)
Something like the best of both pre-Qt5 macros and Qt5 compile-time type 
checking, if I understand well the code.
So, I'm impatient to get rid of my not-c++11-ready target platforms.

Moreover am I wrong or is this fully source-compatible with the 
refactoring we talked about (moving a slot across parents and children 
classes) and with overloading slots ?
But probably not binary-compatible.

Thanks.

-- 
Grégoire Barbier :: g à g76r.eu :: +33 6 21 35 73 49



More information about the Development mailing list