6

我已经在库中运行了这段代码很长一段时间:

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>不会改变行为。

4

3 回答 3

6

5.12.0 起,此提交应修复此问题:“在 Qt 命名空间中声明运算符| 以用于该命名空间中的 QFlags”。在 5.12.0 之前,Qt 曾经将其枚举运算符放在全局命名空间(参见qnamespace.h)而不是Qt命名空间中。

问题是当当前命名空间中有另一个运算符匹配时,编译器不会搜索父范围。因此,只要您为命名空间中的任何类型的运算符添加重载,Qt 的重载就不会在匹配集中。ADL通常用于解析在与类型相同的命名空间中声明的运算符,但如果运算符位于不同的命名空间中,这将不起作用。

真正的解决方案是 Qt 将运算符放在与它们操作的类型相同的命名空间中,他们在 5.12.0 中这样做了。如果您坚持使用以前的版本,您可以自己导入运算符:

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

请注意,这可能会产生意想不到的后果,因为您可能会在不应该使用的上下文中提供很多名称。

于 2016-02-06T01:28:26.117 回答
2

检查您的源代码以查看您是否使用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在命名空间内。

于 2016-05-11T04:02:12.687 回答
0

你试过分开| 函数调用的表达式?就像是:

// ..
Qt::WindowFlags flags = Qt::CustomizeWindowHint | Qt::WindowTitleHint;
setWindowFlags( flags );
// ...

只是想看看问题到底出在哪里......

如果是包含问题,那就做#include <QtGui>

于 2012-05-25T13:58:16.713 回答