c++qtqt4qt4.7

QFlags Enum Type Conversion fails all of a sudden


I've had this code running for quite a while in a library:

MyClass::MyClass() 
  : QDialog()
{
    // (...)
    setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowTitleHint );
    // (...)
}

Then, after changing various parts of the library, I get this message all of a sudden:

error C2664: 'QWidget::setWindowFlags': cannot convert parameter 1 from 'int' to 'Qt::WindowFlags'

Apparently it doesn't find the | operator overload provided by the QFlags class so that the result of | returns an int rather than a QFlags construct.

I know I could manually cast the result to (Qt::WindowFlags) and make it work, but QFlags would usually make this kind of cast unnecessary.

Any idea what kind of change could lead to this behaviour?

I am including <QtGui/QDialog> which would usually be sufficient. Including <QtCore/QFlags> doesn't change the behaviour.


Solution

  • Since 5.12.0, this should be fixed by this commit: "Declare the operator| in the Qt namespace for QFlags in that namespaces". Before 5.12.0, Qt used to put its enum operators in the global namespace (see qnamespace.h) instead of in the Qt namespace.

    The problem is that when there is another operator that matches in the current namespace, the compiler will not search the parent scopes. Therefore, as soon as you add an overload for an operator for any type in your namespace, Qt's overloads won't be in the set of matches. ADL is normally used to resolve operators declared in the same namespace as the type, but this doesn't work if the operators are in a different namespace.

    The real solution was for Qt to put operators in the same namespace as the types they operate on, which they did in 5.12.0. If you're stuck with a previous version, you can import the operators yourself:

    using ::operator|;
    setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    

    Note that this may have unintended consequences, as you might be making a lot of names available in a context where they shouldn't.