调用QFlags::testFlag()传入标志位或运算结果引发编译错误的原因
问题解析:testFlag调用多标志位检测的编译错误原因及解决方法
问题描述
尝试通过单个testFlag调用检测两个标志位中是否有一个或全部被设置,代码如下:
myFlags.testFlag(QIODevice::ReadWrite | QIODevice::Append)
触发编译错误:
error: no viable conversion from 'QFlags<QIODevice::OpenMode::enum_type>' (aka 'QFlags<QIODevice::OpenModeFlag>') to 'QIODevice::OpenModeFlag'
已知QIODevice::OpenMode是QFlags<QIODevice::OpenModeFlag>的typedef,QIODevice::OpenModeFlag为枚举类型,完整示例代码:
#include <QTextStream> #include <QIODevice> int main(int argc, char *argv[]) { QTextStream cout(stdout); QIODevice::OpenMode myFlags(QIODevice::ReadWrite); if (myFlags.testFlag(QIODevice::ReadWrite | QIODevice::Append)) cout << "true"; else cout << "false"; }
错误原因
testFlag方法的参数要求是单个QIODevice::OpenModeFlag枚举值,但你传入的QIODevice::ReadWrite | QIODevice::Append会触发隐式类型转换:两个枚举值做按位或运算后,结果会被自动包装成QFlags<QIODevice::OpenModeFlag>类型(也就是QIODevice::OpenMode)。而testFlag不接受这种复合标志位类型的参数,且QFlags无法隐式转回单个枚举值——因为它可能包含多个标志位的组合,没法对应到某个单独的枚举项,因此编译器报错。
解决方法
如果要检测任意一个标志位是否被设置,不能直接给testFlag传组合值,推荐两种实现方式:
方法1:分开调用testFlag
用逻辑或连接两个testFlag调用,只要其中一个标志位存在就返回真:
if (myFlags.testFlag(QIODevice::ReadWrite) || myFlags.testFlag(QIODevice::Append))
方法2:使用按位与运算
利用QFlags重载的按位与运算符,判断结果是否非零——非零即表示至少有一个目标标志位被设置:
if (myFlags & (QIODevice::ReadWrite | QIODevice::Append))
这种写法更简洁,也是Qt中检测多标志位常用的方式。
内容的提问来源于stack exchange,提问作者FutCoder
相关产品推荐
相关产品推荐

