0

I'm writing a subscription manager, the idea is that a signal and slot connection is created and multiple subscriptions can be hooked on the slot, when an update is received all subscriptions to the slot will be notified of the new data.

The issue is, that in my class that manages the subscriptions I am have a method called 'setupSubscription', here is the prototype:

    void setupSubscription(enum eSlotID ID
                          ,const QObject* pobjSender
                          ,const QMetaMethod& pobjSignal
                          ,const QMetaMethod& pobjSlot);

The enumerated type eSlotID contains a unique ID for each slot, the idea is that subscribers simple specify the ID to set-up a subscription.

Its in the early stages of development and the code for setupSubscription:

    void clsSlotSub::setupSubscription(enum eSlotID ID
                                      ,const QObject* pobjSender
                                      ,const QMetaMethod& pobjSignal
                                      ,const QMetaMethod& pobjSlot) {
        QObject::connect(pobjSender, pobjSignal, this, pobjSlot);
    }

Of course there is a lot more to go in this yet, but this causes an error on compile:

    error: no matching function for call to 'clsSlotSub::setupSubscription(clsSlotSub::eSlotID, Fcs::Mount*, void (Fcs::Mount::*)(Fcs::qfloat32), void (clsSlotSub::*)(float))'
                                ,&clsSlotSub::update2Elevation);
                                                              ^

I believe the prototype is correct having single stepped through the connect in the debugger before wrapping it in my setup method.

I'm not sure what the error means as the class implementation and prototype match and are present.

Example of usage:

    msSlotSubMngr.setupSubscription(clsSlotSub::ELEVATION_ANGLE
                                   ,Fcs::Mount::GetRef()
                                  ,&Fcs::Mount::signalElevation
                                  ,&clsSlotSub::update2Elevation);

msSlotSubMngr is an instance of the slot subscription class.

This is the original code before wrapping and this compiles without any error:

    QObject::connect(Fcs::Mount::GetRef()
                    ,&Fcs::Mount::signalElevation
                    ,mpobjElevStrip
                    ,&clsElevStrip::elevationChanged);

When I single set the working code, this is the prototype for the connect method:

     static QMetaObject::Connection connect(const QObject *sender
                                           ,const QMetaMethod &signal
                                           ,const QObject *receiver
                                           ,const QMetaMethod &method
                                           ,Qt::ConnectionType type = Qt::AutoConnection);

Declaration of eSlotID:

    enum eSlotID {
    ...
    /*1003*/   ,ELEVATION_ANGLE
    ...
    };

Slot prototype:

    void update2Elevation(float fltValue);

Slot implementation:

    void clsSlotSub::update2Elevation(float fltValue) {
        qDebug() << "clsSlotSub::New elevation: " << fltValue;
    }
SPlatten
  • 5,334
  • 11
  • 57
  • 128

2 Answers2

0

You need to show your calling code. From the error message, it looks like you just misspelled setupSubscription.

Joey Yandle
  • 141
  • 4
  • Thats not an answer and not really an option either, this should be enough, it includes the prototype and function implementation. – SPlatten May 25 '16 at 10:51
  • Three things are necessary to find the error. You showed two of them. But unless we see the calling code, I have no way of knowing if you passed the correct arguments to the code you showed. – Joey Yandle May 25 '16 at 10:53
  • The parameters passed are exactly the same as if I were to call QObject::connect directly and this works. – SPlatten May 25 '16 at 10:55
  • It looks like you misspelled the function name in your calling code. This would have been obvious if you had posted it. – Joey Yandle May 25 '16 at 11:00
  • What are you talking about? I haven't mispelled anything the caller matches. – SPlatten May 25 '16 at 11:03
  • The error message you posted referred to 'clsSlotSub::setupScription', but the function name is setupSubscription. – Joey Yandle May 25 '16 at 11:05
  • Sorry, that's me typing it into StackOverflow incorrectly, not the actually error. I've copied the actual error now. Thank you. – SPlatten May 25 '16 at 11:05
  • There is nothing wrong with the code you posted. So the problem is in the calling code. You don't have to post the whole thing, but without that callsite no one can help you. – Joey Yandle May 25 '16 at 11:07
  • All I can tell you is that the call to QObject::connect works and the call to setupSubscription with almost the same parameters dosen't. – SPlatten May 25 '16 at 11:09
  • Thanks for adding to the post. The problem is likely either the enum or the second callback. Can you show the enum declaration, and the prototype for both the working and not second callbacks? I.e. clsSlotSub::update2Elevation and clsElevStrip::elevationChanged. – Joey Yandle May 25 '16 at 11:15
  • Added to post, elevationChanged is almost identical. – SPlatten May 25 '16 at 11:20
  • Also the inheritance hierarchy for both clsSlotSub and clsElevStrip are relevant. – Joey Yandle May 25 '16 at 11:20
  • They both inherit from QObject – SPlatten May 25 '16 at 11:20
  • Looking at the full error message, you are requiring the compiler to assume that clsSlotSub is trivially convertible to a Fcs::Mount, and FCS::qfloat32 to float. If either is not possible that is the bug. Can you show the prototype for clsElevStrip::elevationChanged? – Joey Yandle May 25 '16 at 11:25
  • This is the same way that the data is passed to QObject::connect and it doesn't complain, my prototype matches the parameters as declared for QObject::connect. – SPlatten May 25 '16 at 11:26
  • elevationChanged declaration: void elevationChanged(float fltValue); – SPlatten May 25 '16 at 11:27
  • declared in the 'public slots' section of the class. – SPlatten May 25 '16 at 11:27
  • Try replacing the call to setupSubscription with an equivalent call to connect, using the exact same args; leave out the enum and pass the manager as the receiver. – Joey Yandle May 25 '16 at 11:37
  • If that works, then you will have to post a minimally compilable code sample. We've reached the end of what I can do without running the compiler myself. – Joey Yandle May 25 '16 at 11:53
  • Last thing I would suggest is removing the enum keyword from the function prototype, it's not necessary. But AFAIK it shouldn't break anything. – Joey Yandle May 25 '16 at 11:57
  • The only time you can removing the enum keyword is if you create a type def. – SPlatten May 25 '16 at 12:05
0

Found the issue, which had absolutely nothing to do with the prototypes, however the error / cause wasn't reported by the compiler. It turned out that a required header was not included.

SPlatten
  • 5,334
  • 11
  • 57
  • 128