Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

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

    General and Desktop
    3
    10
    3235
    Loading More Posts
    • 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.
    • m4l490n
      m4l490n last edited by

      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?

      1 Reply Last reply Reply Quote 0
      • KillerSmath
        KillerSmath last edited by KillerSmath

        @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

        • http://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE

        @Computer Science Student - Brazil
        Web Developer and Researcher
        “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

        m4l490n 1 Reply Last reply Reply Quote 3
        • m4l490n
          m4l490n @KillerSmath last edited by

          @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.

          1 Reply Last reply Reply Quote 0
          • KillerSmath
            KillerSmath last edited by KillerSmath

            @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 ?

            @Computer Science Student - Brazil
            Web Developer and Researcher
            “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

            m4l490n 1 Reply Last reply Reply Quote 0
            • m4l490n
              m4l490n @KillerSmath last edited by

              @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;

              1 Reply Last reply Reply Quote 0
              • SGaist
                SGaist Lifetime Qt Champion last edited by SGaist

                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.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply Reply Quote 0
                • m4l490n
                  m4l490n last edited by

                  @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!!

                  1 Reply Last reply Reply Quote 1
                  • SGaist
                    SGaist Lifetime Qt Champion last edited by

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

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    m4l490n 1 Reply Last reply Reply Quote 1
                    • m4l490n
                      m4l490n @SGaist last edited by

                      @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.

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        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.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply Reply Quote 2
                        • First post
                          Last post