QFlags枚举类型转换突然失败 [英] QFlags Enum Type Conversion fails all of a sudden

查看:1271
本文介绍了QFlags枚举类型转换突然失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已在代码中运行了一段时间了。

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

部分库,我突然得到这个消息:

 错误C2664:'QWidget :: setWindowFlags':无法转换参数1从'int'到'Qt :: WindowFlags'

显然,由QFlags类提供的运算符过载,使得|的结果返回一个int而不是一个QFlags结构。



我知道我可以手动投射结果到(Qt :: WindowFlags)

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



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

解决方案

p> Qt将其枚举运算符放在全局命名空间 1 中,而不是在 Qt 命名空间中。如果有另一个运算符在当前命名空间中匹配,则编译器将不会搜索父范围 。在你的命名空间中为一个操作符添加一个重载,Qt的重载不会在匹配集合中。 2



a href =http://stackoverflow.com/a/10755710/4885801>以下Fèlix的回答也是无效的,因为它需要两个隐式转换: int - > QFlag - > QFlags 。 Visual C ++将接受它,由于长期以来的错误但是大多数编译器会拒绝它:

 错误:没有可行的从'unsigned int'转换为'Qt :: WindowFlags'
(aka'QFlags< Qt :: WindowType>')
Qt :: WindowFlags f = Qt :: CustomizeWindowHint | Qt :: WindowTitleHint;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这适用于所有编译器:

  Qt :: WindowFlags f(Qt :: CustomizeWindowHint | Qt :: WindowTitleHint); 

因为只需要一次转换: int - > QFlag



真正的解决方案是让Qt将操作符放在同一个命名空间上。在此期间,您可以自行导入运算符:

 使用:: operator |; 
setWindowFlags(Qt :: CustomizeWindowHint | Qt :: WindowTitleHint);

请注意,这可能有意想不到的后果,因为您可能会在上下文中创建很多名称



1 line 1733 命名空间的结尾已在 #n58rel =nofollow> line 58



2 ADL 通常用于解析在与类型相同的命名空间中声明的运算符,但这不会如果操作符位于不同的命名空间中,那么工作。


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.

解决方案

Qt puts its enum operators in the global namespace1 instead of in the Qt namespace. If there is another operator that matches in the current namespace, the compiler will not search the parent scopes. As soon as you add an overload for an operator in your namespace, Qt's overloads won't be in the set of matches.2

Fèlix's answer below is also invalid because it would require two implicit conversions: int -> QFlag -> QFlags. Visual C++ will accept it due to a long-standing bug but most compilers will reject it:

error: no viable conversion from 'unsigned int' to 'Qt::WindowFlags'
    (aka 'QFlags<Qt::WindowType>')
Qt::WindowFlags f = Qt::CustomizeWindowHint | Qt::WindowTitleHint;
                ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This works on all compilers:

Qt::WindowFlags f(Qt::CustomizeWindowHint | Qt::WindowTitleHint);

because only one conversion is required: int -> QFlag.

The real solution is for Qt to put operators in the same namespace as the types they operate on. In the meantime, 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.

1 The closing bracket on line 1733 is the end of namespace Qt that was opened on line 58.

2 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.

这篇关于QFlags枚举类型转换突然失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆