QtGlobal: introduce a helper macro for declaring the RO5 SMFs as defaulted
If a class honors the RO0 we usually just leave a comment in the class' body, and don't explicitly redeclare any of the RO5 special member functions. In some cases we may need to redeclare (some of) them. The main use-case so far is to declare a protected destructor for a base class that is not polymorphic, in order to prevent slicing; the compiler-provided destructor is always public. We can easily declare and default such a protected destructor, but that comes with the problem that now we're violating the RO5 (as far as C++ is concerned, declaring a SMF counts towards the RO5, even if it's immediately defaulted). Specifically: by declaring the destructor, the class loses the compiler-generated move operations, and the copy operations are generated but deprecated. Clang >= 18 warns about this. In such a scenario we *must* redeclare all five SMFs... and default them all. This is boilerplate, therefore I'm adding a macro to streamline it. Apply the new macro to a couple of cases were manual refactoring has already been done. Pick-to: 6.8 6.5 Change-Id: I5dc0ff9770621fbec0b1057c164d0623f901e3e9 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit fcb57391f73d36914e10ba964dbd9b01fe6f3af2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
40dc33a9d3
commit
711b86fa24
@ -83,6 +83,31 @@ QT_BEGIN_NAMESPACE
|
||||
return *this; \
|
||||
}
|
||||
|
||||
/*
|
||||
This macro defines the RO5 special member functions (destructor,
|
||||
copy+move constructors and assignment operators) as defaulted.
|
||||
|
||||
Normally we don't use this macro if we're fine with these functions
|
||||
to be public; we instead leave a comment in the class declaration,
|
||||
something like:
|
||||
|
||||
// compiler-generated special member functions are fine!
|
||||
|
||||
In some cases a class may need to redeclare these functions, for
|
||||
instance if it wants to change their accessibility. Since
|
||||
defaulting all five is boilerplate, use this macro instead.
|
||||
|
||||
Note that the default constructor is not covered, and this macro
|
||||
will prevented its automatic generation.
|
||||
*/
|
||||
|
||||
#define QT_DECLARE_RO5_SMF_AS_DEFAULTED(Class) \
|
||||
~Class() = default; \
|
||||
Class(const Class &) = default; \
|
||||
Class(Class &&) = default; \
|
||||
Class &operator=(const Class &) = default; \
|
||||
Class &operator=(Class &&) = default;
|
||||
|
||||
/*
|
||||
These macros can be used to define tag structs in the preferred way (ie.
|
||||
with explicit default ctor).
|
||||
|
@ -72,11 +72,7 @@ template <bool noex, class Const, class R, class... ArgTypes>
|
||||
class function_ref_base
|
||||
{
|
||||
protected:
|
||||
~function_ref_base() = default;
|
||||
function_ref_base(const function_ref_base &) = default;
|
||||
function_ref_base(function_ref_base &&) = default;
|
||||
function_ref_base &operator=(const function_ref_base &) = default;
|
||||
function_ref_base &operator=(function_ref_base &&) = default;
|
||||
QT_DECLARE_RO5_SMF_AS_DEFAULTED(function_ref_base)
|
||||
|
||||
using BoundEntityType = detail::BoundEntityType<Const>;
|
||||
|
||||
|
@ -32,11 +32,7 @@ template <typename T> struct QListSpecialMethodsBase
|
||||
{
|
||||
protected:
|
||||
QListSpecialMethodsBase() = default;
|
||||
~QListSpecialMethodsBase() = default;
|
||||
QListSpecialMethodsBase(const QListSpecialMethodsBase &) = default;
|
||||
QListSpecialMethodsBase(QListSpecialMethodsBase &&) = default;
|
||||
QListSpecialMethodsBase &operator=(const QListSpecialMethodsBase &) = default;
|
||||
QListSpecialMethodsBase &operator=(QListSpecialMethodsBase &&) = default;
|
||||
QT_DECLARE_RO5_SMF_AS_DEFAULTED(QListSpecialMethodsBase)
|
||||
|
||||
using Self = QList<T>;
|
||||
Self *self() { return static_cast<Self *>(this); }
|
||||
@ -58,11 +54,7 @@ template <typename T> struct QListSpecialMethods : QListSpecialMethodsBase<T>
|
||||
{
|
||||
protected:
|
||||
QListSpecialMethods() = default;
|
||||
~QListSpecialMethods() = default;
|
||||
QListSpecialMethods(const QListSpecialMethods &) = default;
|
||||
QListSpecialMethods(QListSpecialMethods &&) = default;
|
||||
QListSpecialMethods &operator=(const QListSpecialMethods &) = default;
|
||||
QListSpecialMethods &operator=(QListSpecialMethods &&) = default;
|
||||
QT_DECLARE_RO5_SMF_AS_DEFAULTED(QListSpecialMethods)
|
||||
|
||||
public:
|
||||
using QListSpecialMethodsBase<T>::indexOf;
|
||||
|
Loading…
x
Reference in New Issue
Block a user