MSVC2019中通过using将基类protected嵌套enum class提升为public的报错问题
编译报错的核心成因
该问题本质是MSVC2019对C++标准中using声明的访问权限传递规则存在特定场景的实现缺陷,具体逻辑拆解如下:
- 依据C++标准
[namespace.udecl]章节的规则,派生类中通过using 基类::实体名引入的所有实体,其可访问性完全由该using声明在派生类中的位置决定。也就是说,基类protected域内的嵌套枚举,被放置在派生类public区域的using声明引入后,该枚举就成为派生类的public可访问实体,外部代码可以通过派生类的作用域合法访问其所有枚举值——这是GCC、Clang以及后续修复了该缺陷的MSVC版本的合规编译行为,也是示例代码的预期运行效果。 - MSVC2019的错误逻辑出在访问校验的路径上:它在检测嵌套枚举的访问权限时,完全忽略派生类中using声明带来的权限重映射,直接回溯到枚举在基类中定义时的原始protected属性做校验。因此当外部代码通过
Derived::Field::B访问枚举值时,编译器会判定该枚举属于基类的protected成员,不允许类外直接访问,最终触发C2248报错。 - 该实现缺陷有明确的场景局限性:仅针对通过using声明引入的嵌套枚举(包括普通非作用域枚举)存在权限判断偏差,同场景下通过using引入的基类成员函数、普通嵌套类的访问权限传递是完全正常的,不会触发同类误报。
内容的提问来源于stack exchange,提问作者arjen1988
相关产品推荐
相关产品推荐

