Qt Forum

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

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Unsolved Strange MOC related error with Q_DECLARE_METATYPE()

    Qt 6
    metatype moc qt6
    2
    4
    317
    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.
    • oblivioncth
      oblivioncth last edited by oblivioncth

      I'm porting an application from Qt5 to Qt6 and ran into a bizarre issue.

      Minimal Example
      [CMakeLists.txt]

      cmake_minimum_required(VERSION 3.19)
      
      project(MetaTypeIssue VERSION 0.1 LANGUAGES CXX)
      
      set(CMAKE_CXX_STANDARD 17)
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      
      set(CMAKE_AUTOMOC ON)
      
      find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
      find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
      
      set(PROJECT_SOURCES
              main.cpp
              m.h
              foo.h
      )
      if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
          qt_add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
      else()
          add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
      endif()
      
      target_link_libraries(MetaTypeIssue PRIVATE Qt${QT_VERSION_MAJOR}::Core)
      

      [foo.h]

      #ifndef FOO_H
      #define FOO_H
      
      #include <QObject>
      
      class Foo : public QObject
      {
          Q_OBJECT
      
      public:
          Foo() {}
      
      signals:
      
          void sig(std::shared_ptr<int> var);
      };
      
      #endif // FOO_H
      

      [m.h]

      #ifndef BAR_H
      #define BAR_H
      
      #include <QObject>
      
      class Bar : public QObject
      {
          Q_OBJECT
      
      public:
          Bar() {}
      };
      Q_DECLARE_METATYPE(std::shared_ptr<int>);
      
      #endif // BAR_H
      

      [main.cpp]

      #include <QCoreApplication>
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
          return a.exec();
      }
      

      Trying to compile this setup with Qt 6 (6.2.4) results in:

      m.h:13: error: C2908: explicit specialization; 'QMetaTypeId<T>' has already been instantiated
      m.h:13: error: C2766: explicit specialization; 'QMetaTypeId<T>' has already been defined
      qmetatype.h:1132: see previous definition of 'QMetaTypeId<std::shared_ptr<int> >'
      

      Some changes that "prevent" the errors:

      • Change the parameter type of Foo::sig() to be different than that in Q_DECLARE_METATYPE() (obviously breaks functionality)
      • Disable auto-MOC (obviously causes linker errors)
      • Rename m.h to any name that doesn't start with an 'm'
      • Compile with Qt 5 (tested with 5.12.3)

      I was hoping to see if anyone could reproduce this or note if/why this outright shouldn't work if that really is the case for some reason.

      Here is the above MRE for convenience: https://www.mediafire.com/file/lm35jkzipj0hmwy/MetaTypeIssue.zip/file

      The original application was able to use shared_ptr<int> as a signal argument just fine, though it was only through a queued connection briefly before threading changes were made, but I'm pretty sure it worked the same when queued.

      EDIT: Corrected accidental usage of unique_ptr in example code instead of shared_ptr (what it actually was/is).

      M 1 Reply Last reply Reply Quote 0
      • M
        MB12 last edited by MB12

        Hello, were you able to resolve this error?
        I am running into this issue when upgrading from QT5 to QT6. Any ideas on troubleshooting this would be appreciated.

        1 Reply Last reply Reply Quote 0
        • M
          MB12 @oblivioncth last edited by

          @oblivioncth
          This is to confirm that I am able to reproduce the issue on QT 6.4.2 on MacOS.
          The project I am trying to port is much bigger and the filename that results in this error does not start with 'm'.

          [ 25%] Automatic MOC for target MetaTypeIssue
          [ 25%] Built target MetaTypeIssue_autogen
          [ 50%] Building CXX object CMakeFiles/MetaTypeIssue.dir/MetaTypeIssue_autogen/mocs_compilation.cpp.o
          In file included from /var/tmp/meta_issue/build/MetaTypeIssue_autogen/mocs_compilation.cpp:3:
          In file included from /var/tmp/meta_issue/build/MetaTypeIssue_autogen/EWIEGA46WW/moc_m.cpp:10:
          /var/tmp/meta_issue/build/MetaTypeIssue_autogen/EWIEGA46WW/../../../m.h:13:1: error: explicit specialization of 'QMetaTypeId<std::shared_ptr<int>>' after instantiation
          Q_DECLARE_METATYPE(std::shared_ptr<int>);
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          /opt/homebrew/include/QtCore/qmetatype.h:1399:34: note: expanded from macro 'Q_DECLARE_METATYPE'
          #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          /opt/homebrew/include/QtCore/qmetatype.h:1403:12: note: expanded from macro 'Q_DECLARE_METATYPE_IMPL'
          struct QMetaTypeId< TYPE >
          ^~~~~~~~~~~~~~~~~~~
          /opt/homebrew/include/QtCore/qmetatype.h:1122:22: note: implicit instantiation first required here
          enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
          ^
          1 error generated.

          1 Reply Last reply Reply Quote 0
          • M
            MB12 last edited by

            I have created a bug report regarding this. I used the minimal example that you have created in the bug report. Thanks for sharing your minimal example.

            https://bugreports.qt.io/browse/QTBUG-111968

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