在MSVC中缩小到布尔警告的转换

时间:2019-02-12 20:19:24

标签: c++ visual-c++

编译此代码时:

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

是编译器错误还是预期的行为?

1 个答案:

答案 0 :(得分:1)

narrowing conversion定义的相关部分在C ++ 17 [dcl.init.list] / 7中:

  

缩小转换是隐式转换:

     
      
  • [...]
  •   
  • 从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其整数提升后的值将适合目标类型。
  •   

在您的代码B中是具有固定基础类型bool的无范围枚举。在[dcl.enum] / 8中说:

  

对于基础类型固定的枚举,该枚举的值为基础类型的值

,这意味着B的唯一可能值是bool的值,即truefalse。它不能容纳其他值。

由于A::member实际上可以表示B的所有值,因此它不是缩小转换,因此警告是虚假的。