QFlags枚举类型转换失败一下子(QFlags Enum Type Conversion fail

2019-09-17 12:21发布

我有这个代码库中的相当长一段时间运行:

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

然后,改变了图书馆的各个部分后,我得到这个消息一下子:

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

显然,它没有找到| 由QFlags类提供运算符重载,这样的结果| 返回而不是QFlags构建一个int。

我知道我可以在结果手动转换为(Qt::WindowFlags)并使其工作,但通常QFlags会做出这种投不必要的。

任何想法,什么样的变化可能导致这种行为?

我包括<QtGui/QDialog>这通常就足够了。 包括<QtCore/QFlags>不改变行为。

Answer 1:

由于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);

请注意,这可能会产生意想不到的后果,因为你可能会犯很多的情况下,他们不应该使用的名字。



Answer 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在命名空间里。



Answer 3:

你有没有试过分开| 从函数调用体现在哪里? 就像是:

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

只是为了看看究竟在何处的问题是...

如果这是一个问题包括,只是做#include <QtGui>



文章来源: QFlags Enum Type Conversion fails all of a sudden
标签: c++ qt qt4 qt4.7