Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.9
-
None
-
-
1f77e8566 (dev), 6e2c9dc7a (6.8), d833763fc (6.7), a94bc5ad8 (tqtc/lts-6.5), c59152c03 (tqtc/lts-6.2)
Description
The 16 operators that should be enclosed in namespace Qt {} are currently defined at the bottom of QtCore/qnamespace.h in the global namespace.
When any (argument types do not matter at all) operator| is declared in a namespace X, e.g. via the Q_DECLARE_OPERATORS_FOR_FLAGS macro, the `QKeyCombination operator|` (defined in the global namespace) is never found within the namespace X. Therefore, Qt::[Keyboard]Modifier{}|Qt::Key{} finds the operator| declared by the macro QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM([Keyboard]Modifiers). This operator| is either explicitly deleted if QT_TYPESAFE_FLAGS is defined or returns QIncompatibleFlag. Thus the code `pushButton->setShortcut(Qt::CTRL | Qt::Key_Return);` in a function defined within the namespace X does not compile:
error: cannot convert ‘QIncompatibleFlag’ to ‘const QKeySequence&’
or with QT_TYPESAFE_FLAGS defined:
error: use of deleted function ‘constexpr void Qt::operator|(QFlags<Modifier>::enum_type, int)’
https://abseil.io/tips/49 explains this. A particularly relevant quote:
It’s important to place such operators in the same namespace as the user-defined type they’re meant to operate upon: in this case within namespace O. If the operator<< is placed in an outer namespace like :: (the global namespace), that operator will work for a while until someone quite innocently places an unrelated operator<< in namespace ‘O’ for some other type. It takes a bit of discipline but saves a lot of confusion later to follow the simple rule of defining all operators and other associated nonmember functions next to the type’s definition in the same namespace.
For more details, gradual investigation, discussion, explanation and potential workarounds in user code see this KDevelop review thread.