我们现在正在测试使用Ubuntu 18中提供的较新gcc 7.3在QtCreator下编译一些Qt代码(以前在Ubuntu 16下使用gcc 4.9.3)。
Qt因此提供了enum
:
enum CheckState {
Unchecked,
PartiallyChecked,
Checked
};
现在,当我们将三元运算符与此一起使用时:
QVariant MyClass::MyFunc(const QModelIndex &index, int role) const {
return (someCondition ? Qt::Checked : Qt::Unchecked);
}
然后gcc
抱怨(带有警告,但我们将警告视为错误):
prog.cpp:999:99:
error: passing ‘Qt::CheckState’ chooses ‘int’
over ‘uint {aka unsigned int}’ [-Werror=sign-promo]
我们可以通过以下方法解决问题:
return (someCondition ? Qt::Checked : static_cast<int>(Qt::Unchecked));
但是我不确定为什么必须这样做。
由于它们来自完全相同的enum
,因此它们应该是相同的类型,不是吗?我知道存在两个可能值不同类型的潜在问题,但我不明白为什么在这种情况下需要进行这种类型转换。
值是{0, 1, 2}
中的enum
,我认为完全相同类型会排除转换的可能性。
我唯一想到的可能是,由于某种原因,枚举的零值被视为无符号。
答案 0 :(得分:2)
我假设上下文类似于:
struct S
{
S(int);
S(unsigned int);
};
S foo()
{
return (1 ? Qt::Checked : Qt::Unchecked);
}
其中produces warning in gcc 7.3:
警告:通过
Qt::CheckState
会选择int
而不是unsigned int
[-Wsign-promo]
该警告与类型enum CheckState
的值到整数的隐式转换有关。对int
和unsigned int
都进行有效的隐式转换,并且重载分辨率选择int
。
显然,发出警告的理由是,在这种情况下,某些旧版本的gcc选择了unsigned int
,但是gcc 7遵循了Standard并选择了int
。
您的修复之所以有效,是因为在发生重载解析之前,第二和第三操作数被带到了一种常见的int
类型(与您选择的枚举器无关)。
也许适当的解决方法是将static_cast<int>
应用于整个条件,而不仅仅是一个操作数。