[Development] [Interest] Qt5: Problem connecting QTimer::timeout() to lambda

Olivier Goffart olivier at woboq.com
Fri Nov 2 09:41:06 CET 2012


On Thursday 01 November 2012 17:32:20 Thiago Macieira wrote:
> On sexta-feira, 2 de novembro de 2012 00.23.43, Olivier Goffart wrote:
> > Hi,
> > 
> > It is the QPrivateSignal that is breaking it.
> > 
> > It is only possible to connect to functor (lambda are functor) if they
> > have
> > the same number of arguments.  The number need to match exactly, and it is
> > not possible to omit any. (so you may not omit the QPrivateSignal
> > argument)
> > Using C++11 new SFINAE rules, it should be possible to change that.
> > 
> > One hack could be to remove the QPrivateSignal type from the Argument list
> > in the second template parametter of QFunctorSlotObject.
> 
> Why doesn't the code use the number of arguments from the receiver instead
> of the sender? We did that for regular functions and member functions.

Because for regular functions slot, I can knw that.    The arguments are in 
the template argument.

When I do  QtPrivate::FunctionPointer<&MyObject::mySlot>::AgumentCount,  the 
partial template specialisation  is chosen  (imagine mySlot has two arguments)
  
template<class Obj, typename Ret, typename Arg1, typename Arg2> 
struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2)> { 
  enum {ArgumentCount = 2};   ... }

Hence, I know I can call the function with just the two first argument of the 
signal.


However, in the case of a functor, I have not found a way.
struct MyFunctor{ void operator()(); };

then one call QObject::connect<void(QTimer::*)(QTimer::QPrivateSignal), 
MyFunctor>(....)
Then I can know the number of argument of the signal type (using 
QtPrivate::FunctionPointer), but I don't know how to know the number of 
argument of the slot type.
QtPrivate::FunctionPointer<&MyFunctor::operator()> will not work in case there 
are several operator().

With C++11, it would be possible to do something like

template<typename Functor, typename ... SignalArgs> 
test(Functor&f, SignalArgs... &args) -> enable_if<(sizeof(f(args...))>0),yes>;

And if it does not exist, try removing the last argument from signal args and 
see if that exist.


Something like that could be done for Qt 5.1  (or even maybe Qt 5.0)  But I 
don't know how to do it without C++11.

And connecting to functor works without C++11  (now, it is probably ok to say 
that connecting to functor with less arguments than the signal is only working 
with C++11)

-- 
Olivier

Woboq - Qt services and support - http://woboq.com






More information about the Development mailing list