编译此代码时:
enum B: bool { T = true };
struct A { bool member; };
void foo(const B b = T)
{
A a{b}; // warning here
}
void bar()
{
const B b = T;
A a{b};
}
MSVC在foo
中发出警告:
警告C4838:从'const B'到'bool'的转换需要缩小转换范围
但可以很好地编译bar
。
这里是proof
是编译器错误还是预期的行为?
答案 0 :(得分:1)
narrowing conversion定义的相关部分在C ++ 17 [dcl.init.list] / 7中:
缩小转换是隐式转换:
- [...]
- 从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其整数提升后的值将适合目标类型。
在您的代码B
中是具有固定基础类型bool
的无范围枚举。在[dcl.enum] / 8中说:
对于基础类型固定的枚举,该枚举的值为基础类型的值
,这意味着B
的唯一可能值是bool
的值,即true
和false
。它不能容纳其他值。
由于A::member
实际上可以表示B
的所有值,因此它不是缩小转换,因此警告是虚假的。