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

Olivier Goffart olivier at woboq.com
Fri Nov 2 00:23:43 CET 2012


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.

-- 
Olivier

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


On Thursday 01 November 2012 13:03:56 Stephen Chu wrote:
> I find out what QPrivateSignal is for but it's not clear if lambda can
> still be used to connect to such private signals.
> 
> If I connect QTimer::timeout() to a slot that takes no argument, it
> compiles fine. But when I try to connect to a lambda function without
> any argument, the results in the mentioned error.
> 
> Is this designed behavior? It makes using lambda function as slot really
> hard since there's no mention in documentation which signals are limited
> this way.
> 
> FYI. I am using clang 3.1.
> 
> On 11/1/12 11:18 AM, Stephen Chu wrote:
> > I just updated from Qt5 git and the following code results in compile 
error:
> > 	QTimer timer;
> > 	connect(&timer, &QTimer::timeout, [=](){});
> > 
> > Error resulted from clang 3.1:
> > 
> > /Qt/5.0/qtbase/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:
> > 395:13: error: no matching function for call to object of type
> > 'PageLogPanel::<lambda at
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36>'
> > 
> >               f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type
> > 
> > *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
> > 
> >               ^
> > 
> > /Qt/5.0/qtbase/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:
> > 434:79: note: in instantiation of member function
> > 'QtPrivate::FunctorCall<QtPrivate::IndexesList<0>,
> > QtPrivate::List<QTimer::QPrivateSignal>, void, PageLogPanel::<lambda at
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36> >::call' requested here
> > 
> >               FunctorCall<typename Indexes<N>::Value, SignalArgs, R,
> > 
> > Function>::call(f, arg);
> > 
> >          ^
> > 
> > /Qt/5.0/qtbase/include/QtCore/../../src/corelib/kernel/qobject_impl.h:193:
> > 17: note: in instantiation of function template specialization
> > 'QtPrivate::Functor<PageLogPanel::<lambda at
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36>,
> > 1>::call<QtPrivate::List<QTimer::QPrivateSignal>, void>' requested here
> > 
> >                   FuncType::template call<Args,
> > 
> > R>(static_cast<QFunctorSlotObject*>(this_)->function, r, a);
> > 
> >                   ^
> > 
> > /Qt/5.0/qtbase/include/QtCore/../../src/corelib/kernel/qobject_impl.h:202:
> > 71: note: in instantiation of member function
> > 'QtPrivate::QFunctorSlotObject<PageLogPanel::<lambda at
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36>, 1,
> > QtPrivate::List<QTimer::QPrivateSignal>, void>::impl' requested here
> > 
> >           explicit QFunctorSlotObject(const Func &f) :
> > QSlotObjectBase(&impl), function(f) {}
> > 
> >                                                                         ^
> > 
> > /Qt/5.0/qtbase/include/QtCore/../../src/corelib/kernel/qobject.h:285:32:
> > note: in instantiation of member function
> > 'QtPrivate::QFunctorSlotObject<PageLogPanel::<lambda at
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36>, 1,
> > QtPrivate::List<QTimer::QPrivateSignal>, void>::QFunctorSlotObject'
> > requested here
> > 
> >                              new QtPrivate::QFunctorSlotObject<Func2,
> > 
> > SignalType::ArgumentCount, typename SignalType::Arguments, typename
> > SignalType::ReturnType>(slot),
> > 
> >                                  ^
> > 
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:2: note: in instantiation
> > of function template specialization 'QObject::connect<void
> > (QTimer::*)(), PageLogPanel::<lambda at
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36> >' requested here
> > 
> >           connect(&timer, &QTimer::timeout, [=](){});
> >           ^
> > 
> > ../../Dropbox/Client2012/PageLogPanel.cpp:47:36: note: candidate
> > function not viable: requires 0 arguments, but 1 was provided
> > 
> >           connect(&timer, &QTimer::timeout, [=](){});
> >           
> >                                             ^
> > 
> > It seems
> > http://qt.gitorious.org/qt/qtbase/commit/dee57bc91080740201a0bf0b8c42eb374
> > ee696f3 added QPrivateSignal to the signal signature?
> > _______________________________________________
> > Interest mailing list
> > Interest at qt-project.org
> > http://lists.qt-project.org/mailman/listinfo/interest
> 
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development



More information about the Development mailing list