编译此代码时:
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中发出警告:
warning C4838: conversion from ‘const B’ to ‘bool’ requires a narrowing conversion
但编译条很好.
这是一个proof
它是编译器错误还是预期的行为?
最佳答案
narrowing conversion定义的相关部分在C 17 [dcl.init.list] / 7中:
A narrowing conversion is an implicit conversion:
- […]
- from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
在你的代码中,B是一个带有固定底层类型bool的无范围枚举.在[dcl.enum] / 8中它说:
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type
这意味着B的唯一可能值是bool的值,即true和false.它不能容纳其他价值观.
由于A :: member实际上可以表示B的所有值,因此它不是缩小转换,因此警告是假的.