C++ gcc7中的枚举和三元奇怪行为

C++ gcc7中的枚举和三元奇怪行为,c++,qt,gcc,enums,C++,Qt,Gcc,Enums,我们现在正在测试使用Ubuntu18中更新的GCC7.3在QtCreator下编译一些Qt代码(我们以前在Ubuntu16下使用GCC4.9.3) Qt提供了一个枚举,因此: enum CheckState { Unchecked, PartiallyChecked, Checked }; 现在,当我们使用三元运算符时: QVariant MyClass::MyFunc(const QModelIndex &index, int role) const {

我们现在正在测试使用Ubuntu18中更新的GCC7.3在QtCreator下编译一些Qt代码(我们以前在Ubuntu16下使用GCC4.9.3)

Qt提供了一个
枚举
,因此:

enum CheckState {
    Unchecked,
    PartiallyChecked,
    Checked
};
现在,当我们使用三元运算符时:

QVariant MyClass::MyFunc(const QModelIndex &index, int role) const {
    return (someCondition ? Qt::Checked : Qt::Unchecked);
}
然后,
gcc
投诉(带有警告,但我们将警告视为错误):

我们可以通过以下方式解决该问题:

return (someCondition ? Qt::Checked : static_cast<int>(Qt::Unchecked));
return(someCondition?Qt::Checked:static_cast(Qt::Unchecked));
但我不知道为什么这是必要的

因为它们来自完全相同的
enum
,所以它们应该是相同的类型,不是吗?我知道在两个可能的值是不同类型的情况下存在潜在的问题,但我不理解为什么在这种情况下需要进行这种类型转换

值是
enum
中的
{0,1,2}
,我认为完全相同的类型否定了任何转换的可能性


我能想到的唯一可能性是,出于某种原因,枚举的零值被视为无符号。

我假设上下文类似于MCVE,而不是MCVE:

struct S
{
    S(int);
    S(unsigned int);
};

S foo()
{
    return (1 ? Qt::Checked : Qt::Unchecked);
}
其中:

警告:传递
Qt::CheckState
选择
int
而不是
unsigned int
[-Wsign promo]


警告与类型
enum CheckState
的值隐式转换为整数有关。存在到
int
无符号int
的有效隐式转换,重载解析选择
int

显然,发出警告的理由是,在这种情况下,一些较旧版本的gcc选择了
unsigned int
,但gcc 7遵循标准并选择
int

您的修复之所以有效,是因为在重载解析发生之前,第二个和第三个操作数被转换为一种常见的
int
(这与您选择的枚举数无关)


也许一个合适的修复方法是将
static\u cast
应用于整个条件运算,而不仅仅是一个操作数

M.M.,我想你可能是对的。我一直在尝试让一个返回值为int和unsigned int的MCVE运行,但是失败没有出现。实际代码返回一个<代码> qValue,它几乎肯定有许多类型的构造函数(),包括<代码> qValm(int VALL)和<代码> qVALUT(Uint VALL)< /代码>。在我看来,如果值来自同一个枚举,编译器不应该将它们视为不同的类型。@paxdiablo它们没有被视为不同的类型。条件的结果具有类型
enum CheckState
,警告来自尝试将
enum CheckState
隐式转换为
QVariant
。如果将代码更改为
returnqt::Checked,则可能会收到相同的警告正确。啊,我想我现在明白了。这实际上与三元无关,只是警告gcc更喜欢一种转换而不是另一种转换,这在逻辑上是在选择过程之后。删除任何一个构造函数都可以解决这个问题(当然,这不是RealQT的选项,也不是我们的代码)。铸造我们返回的整个表达式也修复了它,并允许我批准带有我的强迫症倾向的PR:-)感谢您的帮助。FWIW,我们使用了
return static_cast(1?Qt::Checked:Qt::Unchecked)
struct S
{
    S(int);
    S(unsigned int);
};

S foo()
{
    return (1 ? Qt::Checked : Qt::Unchecked);
}