Cannot register structs/classes with Q_DECLARE_METATYPE
-
Hey guys, i have a little problem.
When compiling code, i ran into this error:/home/*****/work/*****/*****/*****/src/common/common_data/GlobalChannelIdentifier.h:34:1: required from here /usr/include/c++/12/type_traits:1012:52: error: static assertion failed: template argument must be a complete class or an unbounded array 1012 | static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
Looks like problem is with registering GlobalChannelIdentifier struct.
Error occurs on tihs line: "Q_DECLARE_METATYPE(GlobalChannelIdentifier)":struct GlobalChannelIdentifier : std::pair<std::uintptr_t, int> { using pair::pair; struct Hash { std::size_t operator()(const GlobalChannelIdentifier &gi) const noexcept; }; friend std::ostream &operator<<(std::ostream &s, const GlobalChannelIdentifier &id); }; GlobalChannelIdentifier GetGlobalChannelIdentifier(const GlobalChannelParams &gci) noexcept; Q_DECLARE_METATYPE(GlobalChannelIdentifier)
There are more errors when registering another classes or structs in project.
Does anybody know, where could be a problem?
Thank you very much.PS.: yes, i have included <QMetaType>
-
Hi and welcome to devnet,
I don't have a machine at hand to test but I wonder if you should not use Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE since your type derives from std::pair.
Or maybe, you might need to also declare a meta type for
std::uintptr_t
. -
@SGaist Thanks for reply!
Unfortunately registering std::pair template is not working, teplate is already registered:
/home/work/*****/src/common/common_data/GlobalChannelIdentifier.h:35:1: error: redefinition of ‘struct QMetaTypeId<std::pair<_T1, _T2> >’
35 | Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::pair)And declaring meta type for std::uintptr_t doesnt work out too.
Could u try the code on your system please? This problem occured while transitioning code from qt5 to qt6.
Thanks! -
@markovvv
Something else is wrong here, I suspect.
The code compiles for me (Linux x86_64, Qt 6.7, 6.8) -
@markovvv
In addition to @Axel-Spoerl, which distribution are you using ?
Which version of gcc ? -
This code compiles as-is for me (Qt 6.6)
#include <QCoreApplication> #include <utility> struct GlobalChannelParams { }; // faked struct GlobalChannelIdentifier : std::pair<std::uintptr_t, int> { using pair::pair; struct Hash { std::size_t operator()(const GlobalChannelIdentifier &gi) const noexcept; }; friend std::ostream &operator<<(std::ostream &s, const GlobalChannelIdentifier &id); }; GlobalChannelIdentifier GetGlobalChannelIdentifier(const GlobalChannelParams &gci) noexcept; Q_DECLARE_METATYPE(GlobalChannelIdentifier) int main(int argc, char **argv) { QCoreApplication app(argc, argv); return 0; }
Using either of these:
g++-11 (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 // platform default g++-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
So this does not seem to be an obvious compiler version issue.
-
@markovvv
I am on openSuSE Tumbleweed, it compiles with gcc12 and 13.
Reading the compile error again, you may wanna check whether#include <utility>
is missing or skipped by a pragma. Looks the compiler doesn't knowstd::pair
, whenQ_DECLARE_METATYPE
is expanded. -
Thanks u guys for all of the input! @Axel-Spoerl utility is included. Since iam transfering application from qt5 to qt6, is there any possibility, that there is a qt version collision? Iam out of the ideas, what could be possibly wrong. Application on qt5 compiled fine.
-
Really hard to guess.
If out of ideas, I'd start isolating the conflicting behavior into a small reproducer and see whether it happens there. Even if utilities are included and recognized by the code model of your IDE, the compiler might still not see it due to #ifdef'ry or pragma one cascades. -
@markovvv said in Cannot register structs/classes with Q_DECLARE_METATYPE:
Yeah, it does
So it has neither something to do with the Qt version nor with the compiler but with your code (organisation) - reduce your code until the error is gone and you found the problem.