问题
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.
回答1:
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.
回答2:
Check your source code to see if you use Q_DECLARE_OPERATORS_FOR_FLAGS
to declare your own flags somewhere in a namespace before where you got the compile error.
As @isanae said, If there is another operator that matches in the current namespace, ...
. So you should not put the other operator that might be matching.
The solution is to put all your own Q_DECLARE_OPERATORS_FOR_FLAGS
declaration in global namespace, just as what Qt does.
Hope this could be helpful. I hit the same issue when I put everything into a unity build environment, and I switch the order of source codes and finally located the code snippet that causes this problem: one Q_DECLARE_OPERATORS_FOR_FLAGS
inside a namespace.
回答3:
Have you tried to separate the | expression from the function calling? Something like:
// ..
Qt::WindowFlags flags = Qt::CustomizeWindowHint | Qt::WindowTitleHint;
setWindowFlags( flags );
// ...
Just to see where exactly the problem is...
If it's a problem of includes, just do #include <QtGui>
来源:https://stackoverflow.com/questions/10755058/qflags-enum-type-conversion-fails-all-of-a-sudden