Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Slot & signal argument count difference - how to deal with?
Forum Updated to NodeBB v4.3 + New Features

Slot & signal argument count difference - how to deal with?

Scheduled Pinned Locked Moved Solved General and Desktop
signal & slot
6 Posts 3 Posters 632 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • artwawA Offline
    artwawA Offline
    artwaw
    wrote on last edited by
    #1

    Good morning,
    I have a rather general question related to the topic.

    I have a slot function like this:
    void MyClass::request(const QString &arg = QString()); where inside I make a choice based on arg.isEmpty().

    Now when I try to make a connection like this:
    connect(ui->edit,&QLineEdit::returnPressed,this,&MyClass::request);
    compiler throws out an error (shortened version):

    error: static assertion failed due to requirement 'int(FunctionPointer<void (QLineEdit::*)()>::ArgumentCount) >= int(FunctionPointer<void (MyClass::*)(const QString &)>::ArgumentCount)': The slot requires more arguments than the signal provides.
            static_assert(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

    Usually I deal with it by wrapping the connect into lambda so it is not a stopping issue but I was just wondering - can this be done differently? The argument missing from the signal does not matter as it becomes a QString() anyway.

    Many thanks in advance.

    For more information please re-read.

    Kind Regards,
    Artur

    J.HilkJ 1 Reply Last reply
    0
    • artwawA artwaw

      Good morning,
      I have a rather general question related to the topic.

      I have a slot function like this:
      void MyClass::request(const QString &arg = QString()); where inside I make a choice based on arg.isEmpty().

      Now when I try to make a connection like this:
      connect(ui->edit,&QLineEdit::returnPressed,this,&MyClass::request);
      compiler throws out an error (shortened version):

      error: static assertion failed due to requirement 'int(FunctionPointer<void (QLineEdit::*)()>::ArgumentCount) >= int(FunctionPointer<void (MyClass::*)(const QString &)>::ArgumentCount)': The slot requires more arguments than the signal provides.
              static_assert(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      

      Usually I deal with it by wrapping the connect into lambda so it is not a stopping issue but I was just wondering - can this be done differently? The argument missing from the signal does not matter as it becomes a QString() anyway.

      Many thanks in advance.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @artwaw thats what QOverload is for:

      https://doc.qt.io/qt-5/qtglobal.html#qOverload


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      artwawA 1 Reply Last reply
      1
      • J.HilkJ J.Hilk

        @artwaw thats what QOverload is for:

        https://doc.qt.io/qt-5/qtglobal.html#qOverload

        artwawA Offline
        artwawA Offline
        artwaw
        wrote on last edited by
        #3

        @J-Hilk Thank you. I was vaguely aware of its existence but never used. Will learn to use that.

        For more information please re-read.

        Kind Regards,
        Artur

        JonBJ 1 Reply Last reply
        1
        • artwawA artwaw has marked this topic as solved on
        • artwawA artwaw

          @J-Hilk Thank you. I was vaguely aware of its existence but never used. Will learn to use that.

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by JonB
          #4

          @artwaw
          I do not believe @J-Hilk's suggestion of qOverload() is for this case/works here (unless he corrects me/knows better). It is for distinguishing between multiple potential slot functions to connect to a signal where there is more than one overload for the slot. This is not your issue here.

          connect(ui->edit, &QLineEdit::returnPressed,
                  this, qOverload<const QString &>(&MyClass::request));
          

          gives me the same error as you get now. All tested with Qt5.15 and g++ -c -std=gnu++1z (gcc 11.4).

          I believe that you cannot directly call a slot method which has an extra argument over what the signal sends, even if the slot specifies a default for that argument to make it "optional". I believe you need to connect with a lambda to achieve that.

          connect(ui->edit, &QLineEdit::returnPressed,
                  this, [this]() { request(); });
          

          Somewhat oddly, it seems that you can even connect to "extra default arg" if you do it in-line via a lambda:

          connect(ui->edit, &QLineEdit::returnPressed,
                  this, [this](const QString &arg = QString() ){});
          

          is accepted. But if you try to put a method (with an optional argument) there it errors. One would have thought they would be equivalent, but apparently not. If a C++ expert would care to comment on this difference I should be interested :)

          J.HilkJ 1 Reply Last reply
          1
          • JonBJ JonB

            @artwaw
            I do not believe @J-Hilk's suggestion of qOverload() is for this case/works here (unless he corrects me/knows better). It is for distinguishing between multiple potential slot functions to connect to a signal where there is more than one overload for the slot. This is not your issue here.

            connect(ui->edit, &QLineEdit::returnPressed,
                    this, qOverload<const QString &>(&MyClass::request));
            

            gives me the same error as you get now. All tested with Qt5.15 and g++ -c -std=gnu++1z (gcc 11.4).

            I believe that you cannot directly call a slot method which has an extra argument over what the signal sends, even if the slot specifies a default for that argument to make it "optional". I believe you need to connect with a lambda to achieve that.

            connect(ui->edit, &QLineEdit::returnPressed,
                    this, [this]() { request(); });
            

            Somewhat oddly, it seems that you can even connect to "extra default arg" if you do it in-line via a lambda:

            connect(ui->edit, &QLineEdit::returnPressed,
                    this, [this](const QString &arg = QString() ){});
            

            is accepted. But if you try to put a method (with an optional argument) there it errors. One would have thought they would be equivalent, but apparently not. If a C++ expert would care to comment on this difference I should be interested :)

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @JonB you're right, this is with default arguments in the slot functions, didn't see that.

            Thats tricky and there's only really 3 ways to do this:

            class MyClass2 : public QObject {
                Q_OBJECT
            public:
                MyClass2(QObject *parent = nullptr) : QObject(parent)
                {
                    //1 Lambda
                    connect(this, &MyClass2::mySignal, this, [this]() { request(); });
                    
                    //2other slot
                    connect(this, &MyClass2::mySignal, this, &MyClass2::requestVanialla);
                    
                    //3 binds
                    connect(this, &MyClass2::mySignal, std::bind(&MyClass2::request, this, QLatin1String()));
                    
                }
            
            signals:
                void mySignal();
            
            public slots:
                void request(const QString & request = QLatin1String()) {
                    //do Stuff here
                    qDebug() << request;
                }
                
                void requestVanialla() {request();}
            };
            

            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            3
            • artwawA Offline
              artwawA Offline
              artwaw
              wrote on last edited by
              #6

              Thank you, Gentlemen. I indeed ran into a method "ambiguous" error while trying with qOverload but since I've been using lambdas (as signposted "1 Lambda" in the post above) I decided to investigate that later on under the assumption I misunderstood something. Now it is clear I did not :)
              At any rate, I learned something new from your answers today and am grateful.
              Have a lovely day!

              For more information please re-read.

              Kind Regards,
              Artur

              1 Reply Last reply
              1

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved