Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

how do I solve the error: specializing member requires 'template<>' syntax?



  • I'm trying to emit a signal from one thread to another, the signal has to emit a custom datatype. The whole contents of my thread class are:

    /#ifndef DEVICEPRESENCE_H
    #define DEVICEPRESENCE_H
    
    #include <QThread>
    #include <QObject>
    #include <QSerialPortInfo>
    #include <QList>
    #include <QMetaType>
    
    typedef QList<QSerialPortInfo> AvailablePorts;
    qRegisterMetaType<AvailablePorts>("AvailablePorts");
    
    class DevicePresence : public QThread
    {
        Q_OBJECT
    
    public:
        explicit DevicePresence(QObject *parent = 0);
    
        void run();
    
    signals:
        void devicesChanged(AvailablePorts m_availablePorts);
    
    private:
        AvailablePorts m_availablePorts;
    };
    
    #endif // DEVICEPRESENCE_H
    

    But when I compile the code I get the error:

    devicepresence.h:12: error: specializing member ‘::qRegisterMetaType<AvailablePorts>’ requires ‘template<>’ syntax
    qRegisterMetaType<AvailablePorts>("AvailablePorts");
    ^

    I'm not really sure what I need to do here, I followed the steps in nt qRegisterMetaType(const char *typeName) which states:

    typedef QString CustomString;
    qRegisterMetaType<CustomString>("CustomString");
    

    So that's what I did.

    Am I missing something?



  • @m4l490n said in how do I solve the error: specializing member requires 'template<>' syntax?:

    QSerialPortInfo

    You can declare a new type using a macro
    Q_DECLARE_METATYPE(AvailablePorts)

    Code

    ...
    typedef QList<QSerialPortInfo> AvailablePorts;
    
    Q_DECLARE_METATYPE(AvailablePorts)
    ...
    

    References



  • @KillerSmath thanks for helping.

    When I do that then it compiles fine but when I try to run it I get:

    QObject::connect: Cannot queue arguments of type 'AvailablePorts'
    (Make sure 'AvailablePorts' is registered using qRegisterMetaType().)
    QThread: Destroyed while thread is still running
    The program has unexpectedly finished.
    The process was ended forcefully.



  • @m4l490n

    Everything is working well to me, but okay, i have some questions:

    • Where are you declaring the metatype ?
    • Can you show me your connection code ?


  • @KillerSmath I'm declaring it on the "devicepresence.h" header file for my class whose contents I posted on the original question. The connection code is as follows:

     connect(devicePrecenseThread, &DevicePresence::devicesChanged, this, &MainWindow::refreshDevicesList);
    

    And in "mainwindow.h" I have the private slot void refreshDevicesList(AvailablePorts availablePorts); as well as the private member DevicePresence *m_devicePrecenseThread;


  • Lifetime Qt Champion

    Hi,

    IIRC, that error indicates you need to also provide the QDataStream operators for your custom type or at leat for QSerialPortInfo so that they can be stored into/loaded from QVariant.

    Wrong memory, the QDataStream operators missing triggers another error clearly stating that the data cannot be loaded/stored with Variants.



  • @KillerSmath and @SGaist After struggling a lot with this I was reading again the int qRegisterMetaType(const char *typeName) documentation and I read that:

    "This function is useful to register typedefs so they can be used by QMetaProperty, or in QueuedConnections"

    So I thought; well if it is a function it should go inside a method. So I put it in the constructor in the .cpp file:

    DevicePresence::DevicePresence(QObject *parent) :
        QThread(parent)
    {
        qRegisterMetaType<AvailablePorts>("AvailablePorts");
    }
    

    And now everything is working perfectly fine!!

    To be honest, I don't know why it is working now, but this seems much simpler than what @SGaist proposes.

    I have no idea why it is working and it would be really useful if someone could please explain why this works to be able to flag that as the correct answer because nevertheless my issue was solved, I don't think this should be closed until I know what happened, also might be helpful if someone else finds the same issue.

    Thanks for helping!!


  • Lifetime Qt Champion

    Where did you had the original qRegisterMetaType<AvailablePorts> call ?



  • @SGaist if you see the original question I posted the contents of the devicepresence.h file. I got confused by the documentation and I declared my typedef on line 10 and then I put qRegisterMetaType<AvailablePorts>("AvailablePorts") on line 11.

    So I saw this in the documentation:

    typedef QString CustomString;
    qRegisterMetaType<CustomString>("CustomString");
    

    And I did this in the devicepresence.h file:

    typedef QList<QSerialPortInfo> AvailablePorts;
    qRegisterMetaType<AvailablePorts>("AvailablePorts");
    

    But the documentation doesn't contain any examples that illustrate where you have to put that and since I'm coming from C and I'm used to putting the typedefs in the .h files and I'm not familiar yet with the <> notation which confused me into not being sure if qRegisterMetaType<AvailablePorts>("AvailablePorts") was a function or not, then I ended up putting it in the devicepresence.h file immediately after the typedef declaration.


  • Lifetime Qt Champion

    Thanks for the clarification. It's not always clear from posted code whether the example is the current code or some snippet.

    In any case, where you call qRegisterMetaType depends on how your code is managed (is it a library that you provide, etc.). If it's your own application, you can simply do it in the main function after you instantiated QApplication. That way you don't lose time calling it again each time you construct a DevicePresence object.


Log in to reply