Hans Olsson
Hans Olsson

Reputation: 12517

Compilation problem with Qt6 and class specific operator new

Consider a class with custom operator new.

class BaseClass {
  void* operator new(size_t size);
  void operator delete(void* p);
};

class MyClass : public BaseClass {
public:
  MyClass(int);
};

And then using MyClass as an argument for a signal and slot in Qt

With Qt5 that works, but with Qt6 that generates compilation errors deep in QMetaType when using Visual Studio 2019, by failing to find a class-specific placement new for MyClass.

Compilation error with VS 2019 (changed to hide specific paths and class-names):

...QtCore\qmetatype.h(2313): error C2660: 'BaseClass::operator new': function does not take 3 arguments
: note: see declaration of 'BaseClass::operator new'
...QtCore\qmetatype.h(2310): note: while compiling class template member function 'QtPrivate::QMetaTypeInterface::CopyCtrFn QtPrivate::QMetaTypeForType<T>::getCopyCtr(void)'
        with
        [
            T=Ty
        ]
...QtCore\qmetatype.h(2370): note: see reference to class template instantiation 'QtPrivate::QMetaTypeForType<T>' being compiled
        with
        [
            T=Ty
        ]
...QtCore\qmetatype.h(2494): note: see reference to class template instantiation 'QtPrivate::QMetaTypeInterfaceWrapper<Ty>' being compiled
...QtCore\qmetatype.h(2537): note: see reference to function template instantiation 'const QtPrivate::QMetaTypeInterface *QtPrivate::qTryMetaTypeInterfaceForType<Unique,QtPrivate::TypeAndForceComplete<MyClass &,std::false_type>>(void)' being compiled
    with
    [
        Unique=qt_meta_stringdata_..._t
    ]
moc_xxx.cpp(286): note: see reference to variable template 'const QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray<qt_meta_stringdata_ModelBrowser_t,QtPrivate::TypeAndForceComplete<ModelBrowser,std::integral_constant<bool,1> >,QtPrivate::TypeAndForceComplete<void,std::integral_constant<bool,0> >,QtPrivate::TypeAndForceComplete<void,std::integral_constant<bool,0> >,QtPrivate::TypeAndForceComplete<MyClass &,std::integral_constant<bool,0> >,QtPrivate::TypeAndForceComplete<void,std::integral_constant<bool,0> >,QtPrivate::TypeAndForceComplete<MyClass &,std::integral_constant<bool,0> >,QtPrivate::TypeAndForceComplete<void,std::integral_constant<bool,0> >,...[58]' being compiled

Trying to add generic class-specific placement new (that is void* operator new(size_t size, std::align_val_t, void*) ) seem possible for VS 2019, but not according to the standard and fails in other compilers.

Upvotes: 1

Views: 439

Answers (1)

Hans Olsson
Hans Olsson

Reputation: 12517

The following is just a work-around, and it does not always work - but it is trivial:

class MyClass : public BaseClass {
public:
  MyClass(int);

  MyClass()=delete;
  MyClass(const MyClass&)=delete;
}

The reason it works is that QMetaType has guarded the problematic calls by std::is_default_constructible_v and std::is_copy_constructible_v.

Upvotes: 0

Related Questions