我已经将这段代码在库中运行了很长时间:
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>
不会改变行为。
答案 0 :(得分:5)
从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);
请注意,这可能会产生意想不到的后果,因为您可能会在不应该使用的情况下提供大量名称。
答案 1 :(得分:1)
检查源代码,看看是否使用If there is another operator that matches in the current namespace, ...
在编译错误之前在命名空间的某处声明自己的标志。
正如@isanae所说,Q_DECLARE_OPERATORS_FOR_FLAGS
。所以你不应该放置可能匹配的其他运算符。
解决方案是将所有自己的Q_DECLARE_OPERATORS_FOR_FLAGS
声明放在全局命名空间中,就像Qt所做的那样。
希望这可能有所帮助。当我将所有内容放入统一构建环境时,我遇到了同样的问题,我切换了源代码的顺序,最后找到导致此问题的代码片段:命名空间内有一个{{1}}。
答案 2 :(得分:0)
您是否尝试将|分开?来自函数调用的表达式?类似的东西:
// ..
Qt::WindowFlags flags = Qt::CustomizeWindowHint | Qt::WindowTitleHint;
setWindowFlags( flags );
// ...
只是为了看看问题究竟在哪里......
如果是包含问题,请执行#include <QtGui>