Using std::function as parameter for slot and signal



  • Hi!
    How to set object of std::function as parameter for signal and slot?

    Example:

    signals:
        void sendSetProcFunc(const std::function<void (const QImage &,
                                                   QList<QPolygon> &,
                                                   QList<QImage> &)>
                         &procFunc);
    
    ...................................
    public slots:
        void onSetProcFunc(const std::function<void (const QImage &,
                                                   QList<QPolygon> &,
                                                   QList<QImage> &)>
                         &procFunc);
    

    Building in Qt 5.7 with MinGW_32bit gives next errors:


    debug\moc_QtCVGUI.cpp: In static member function 'static void QtCVGUI::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)':
    debug\moc_QtCVGUI.cpp:131:128: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
    case 2: _t->sendSetProcFunc((reinterpret_cast< const std::function<const void( QImage&,QList<QPolygon>&,QList<QImage>&)>()>(_a[1]))); break;
    ^
    debug\moc_QtCVGUI.cpp:131:142: error: no matching function for call to 'QtCVGUI::sendSetProcFunc(const std::function<const void(QImage&, QList<QPolygon>&, QList<QImage>&)>&)'
    case 2: _t->sendSetProcFunc((reinterpret_cast< const std::function<const void( QImage&,QList<QPolygon>&,QList<QImage>&)>()>(_a[1]))); break;
    ^
    In file included from debug\moc_QtCVGUI.cpp:9:0:
    ****/QtCVGUI.h:49:10: note: candidate: void QtCVGUI::sendSetProcFunc(const std::function<void(const QImage&, QList<QPolygon>&, QList<QImage>&)>&)
    void sendSetProcFunc(const std::function<void (const QImage &,
    ^
    ****/QtCVGUI.h:49:10: note: no known conversion for argument 1 from 'const std::function<const void(QImage&, QList<QPolygon>&, QList<QImage>&)>' to 'const std::function<void(const QImage&, QList<QPolygon>&, QList<QImage>&)>&'


    Removing of all const and setting of std::function as usual variable (NOT reference) solve this problem (i.e. make succesful build).
    Why are there such restrictions and how to bypass them?

    void sendSetProcFunc(std::function<void (QImage &,
                                                   QList<QPolygon> &,
                                                   QList<QImage> &)>
                         procFunc);
    

  • Moderators

    @CrazySiberianScientist said in Using std::function as parameter for slot and signal:

    reinterpret_cast< const std::function<const void( QImage&,QList<QPolygon>&,QList<QImage>&)>

    Shouldn't your cast (why do you use reinterpret_cast actually? What type is _a?) be

    reinterpret_cast< std::function<void(const QImage&,QList<QPolygon>&,QList<QImage>&)>
    

    So, no const in front of std::function, no const in front of void and const for the first parameter.



  • the problem is here QtCVGUI.h:49:10: note: no known conversion for argument 1 from 'const std::function<const void(QImage&, QList<QPolygon>&, QList<QImage>&)>' to 'const std::function<void(const QImage&, QList<QPolygon>&, QList<QImage>&)>&'

    notice std::function<const void vs std::function<void

    Difficult to tell you exactly what went wrong without seeing your emit call but my guess is you are trying to pass a function that has a signature like this: void MyClass::MyFunction(const QImage&, QList<QPolygon>&, QList<QImage>&) const and the final const screws you



  • @VRonin
    In my code there isn't any emit with sendSetProcFunc .


    @jsulm said in Using std::function as parameter for slot and signal:

    Shouldn't your cast (why do you use reinterpret_cast actually? What type is _a?) be

    This isn't my cast, this cast of MOC.


    On bugtracker I created issue : https://bugreports.qt.io/browse/QTBUG-60539


  • Qt Champions 2016

    Probably a deficiency in moc's parsing abilities (no wonder with all the introduced additional complexity in c++11, I might add). Try to typedef and use the alias instead.
    E.g:

    typedef std::function<void (const QImage &, QList<QPolygon> &, QList<QImage> &)> UnnecessaryWrapper;
    
    signals:
        void sendSetProcFunc(const UnnecessaryWrapper & procFunc);
    
    public slots:
        void onSetProcFunc(const UnnecessaryWrapper & procFunc);
    

    Edit:
    I see that Thiago already triaged it as a moc issue. Okay, for the sake of argument try to typedef your argument type.



  • @kshegunov

    I didn't properly check all combinations.
    This builds successfull even without typedef:

    void sendSetProcFunc(const std::function<void (/*const*/ QImage &,
                                                   QList<QPolygon> &,
                                                   QList<QImage> &)>
                         &procFunc);
    
    
    void onSetProcFunc(const std::function<void (/*const*/ QImage &,
                                                   QList<QPolygon> &,
                                                   QList<QImage> &)>
                         &procFunc);
    

  • Qt Champions 2016

    @CrazySiberianScientist said in Using std::function as parameter for slot and signal:

    This builds successfull even without typedef

    Because the moc won't have a const to place at the inappropriate place. My suggestion holds as a possible workaround nonetheless, as const QImage & is profoundly different from QImage &.



  • @kshegunov

    Thank you. Your solution works.
    But don't forget about (may be this is obvious for someone, but I will put this for others):

    int main(){
    ...
       // May be this isn't good place for it
       qRegisterMetaType<UnnecessaryWrapper>("UnnecessaryWrapper");
    ...
    }
    
    
    

  • Qt Champions 2016

    @CrazySiberianScientist said in Using std::function as parameter for slot and signal:

       // May be this isn't good place for it
       qRegisterMetaType<UnnecessaryWrapper>("UnnecessaryWrapper");
    

    This is exactly correct and also an appropriate place, but it is unneeded unless you're going to pass that callback across threads.
    Anyway, I'm glad it worked.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.