@kshegunov
Spiced it up a bit in accordance with your suggestion.
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 Core) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) set(PROJECT_SOURCES main.cpp myclass.h myobject.h myclass.cpp myobject.cpp ) 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)myclass.h
#ifndef MYCLASS_H #define MYCLASS_H #include <QMetaType> #define HEX_ADDR(ptr) QString("0x%1").arg(quint64(ptr), 0, 16) class MyClass { private: int mValue; public: MyClass(); MyClass(int value); MyClass(const MyClass& other); ~MyClass(); int value(); }; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) Q_DECLARE_METATYPE(MyClass); #endif #endif // MYCLASS_Hmyclass.cpp
#include "myclass.h" #include <QDebug> MyClass::MyClass() {} MyClass::MyClass(int value) { mValue = value; } MyClass::~MyClass() { qDebug() << HEX_ADDR(this) << "dead"; } MyClass::MyClass(const MyClass& other) { mValue = other.mValue; qDebug() << HEX_ADDR(this) << "Copied from: " << HEX_ADDR(&other); } int MyClass::value() { return mValue; }myobject.h
#ifndef MYOBJECT_H #define MYOBJECT_H #include <QObject> #include <QDebug> #include "myclass.h" class MyObject : public QObject { Q_OBJECT Q_PROPERTY(MyClass value READ value WRITE setValue NOTIFY valueChanged) private: MyClass mValue; public: MyObject(); MyClass value(); signals: void valueChanged(MyClass newValue); public slots: void setValue(MyClass newValue); }; #endif // MYOBJECT_Hmyobject.cpp
#include "myobject.h" MyObject::MyObject() {} MyClass MyObject::value() { return mValue; } void MyObject::setValue(MyClass newValue) { mValue = newValue; emit valueChanged(mValue); qDebug() << HEX_ADDR(this) << "Update: " << mValue.value(); }main.cpp
#include <QCoreApplication> #include <QTimer> #include <QVariant> #include "myobject.h" #include "myclass.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Test Signal/Slot connection qDebug() << "Setup Signal & Slot test"; MyObject oA; MyObject oB; bool connected = static_cast<bool>(QObject::connect(&oA, &MyObject::valueChanged, &oB, &MyObject::setValue, Qt::QueuedConnection )); qDebug() << "Connection ?: " << connected; oA.setValue(MyClass(777)); // Test Variant qDebug() << "Test Variant"; MyClass sA(4); QVariant var; var.setValue(sA); MyClass sB = var.value<MyClass>(); assert(sA.value() == sB.value()); // Automatically end qDebug() << "Setup quit"; QTimer::singleShot(1000, &a, &QCoreApplication::quit); return a.exec(); }Sample Output:
Setup Signal & Slot test Connection ?: true "0xfed5cff460" Copied from: "0xfed5cff5e8" "0x21aaecfe8a0" Copied from: "0xfed5cff460" "0xfed5cff460" dead "0xfed5cff5d8" Update: 777 "0xfed5cff708" dead Test Variant "0x21aaecfc358" Copied from: "0xfed5cff634" "0xfed5cff694" Copied from: "0x21aaecfc358" Setup quit "0xfed5cfb2d0" Copied from: "0x21aaecfe8a0" "0xfed5cfb1a0" Copied from: "0xfed5cff618" "0xfed5cfb1a0" dead "0xfed5cff608" Update: 777 "0xfed5cfb2d0" dead "0x21aaecfe8a0" dead "0xfed5cff694" dead "0x21aaecfc358" dead "0xfed5cff634" dead "0xfed5cff618" dead "0xfed5cff5e8" deadStill magical with both versions of Qt :)
Will try to pry some more.
EDIT:
Ensured that /Ob0 (MSVC) was set to completely disable inlining and tried changing the data member of MyClass from an int to a QString. Situation is still the same.