我已经在库中运行了这段代码很长一段时间了:
MyClass::MyClass()
: QDialog()
{
// (...)
setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowTitleHint );
// (...)
}
然后,在更改了库的各个部分之后,我突然得到了这个消息:
error C2664: 'QWidget::setWindowFlags': cannot convert parameter 1 from 'int' to 'Qt::WindowFlags'
显然它没有找到| QFlags类提供的运算符重载使得|的结果返回一个int而不是一个QFlags结构。
我知道我可以手动将结果转换为(Qt::WindowFlags)
并使其工作,但QFlags通常会使这种类型的转换不必要。
知道什么样的改变会导致这种行为吗?
我包括<QtGui/QDialog>
,这通常是足够的。包括<QtCore/QFlags>
不会改变行为。
从5.12.0开始,这应该由this commit修复:“在Qt名称空间中为该名称空间中的QFlags声明运算符”。在5.12.0之前,Qt过去常常将其枚举运算符放在全局命名空间(参见qnamespace.h)而不是Qt
命名空间中。
问题是当在当前命名空间中有另一个匹配的运算符时,编译器为will not search the parent scopes。因此,只要为命名空间中的任何类型的运算符添加重载,Qt的重载就不会出现在匹配集中。 ADL通常用于解析在与该类型相同的命名空间中声明的运算符,但如果运算符位于不同的命名空间中,则这不起作用。
真正的解决方案是让Qt将操作符放在与它们操作的类型相同的命名空间中,这是他们在5.12.0中所做的。如果您遇到以前的版本,可以自行导入运算符:
using ::operator|;
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
请注意,这可能会产生意想不到的后果,因为您可能会在不应该出现的情况下提供大量名称。
检查源代码,看看是否使用Q_DECLARE_OPERATORS_FOR_FLAGS
在编译错误之前在命名空间中的某处声明自己的标志。
正如@isanae所说,If there is another operator that matches in the current namespace, ...
。所以你不应该放置可能匹配的其他运算符。
解决方案是将所有自己的Q_DECLARE_OPERATORS_FOR_FLAGS
声明放在全局命名空间中,就像Qt所做的那样。
希望这可能会有所帮助。当我把所有东西都放到统一构建环境中时,我遇到了同样的问题,我切换了源代码的顺序,最后找到导致这个问题的代码片段:命名空间中的一个Q_DECLARE_OPERATORS_FOR_FLAGS
。
你试图分开|来自函数调用的表达式?就像是:
// ..
Qt::WindowFlags flags = Qt::CustomizeWindowHint | Qt::WindowTitleHint;
setWindowFlags( flags );
// ...
只是看看究竟问题在哪里......
如果这是包含的问题,那就做#include <QtGui>