C++20中能否对继承的基类成员使用指定初始化器
结论
你尝试的在派生类指定初始化列表中直接初始化基类成员的写法,不被任何已发布版本的C++标准允许,不存在符合标准的写法可以实现你给出的代码想要的效果。
规则依据
C++20引入的指定初始化器存在严格的语法限制,和C语言的同名特性并不完全兼容,两条核心规则直接否定了该用法的合法性:
- 指定初始化器只能匹配初始化目标聚合类型的直接非静态数据成员,不能跨继承层级访问基类内部声明的成员。
对于你定义的Something2,它作为聚合类型的直接组成只有两部分:隐式的基类Something子对象、自身声明的成员bool Works。DoesntWork是基类Something的内部成员,不属于Something2的直接成员,自然不能直接出现在Something2的初始化指定符列表中。 - 截至C23正式标准,C始终没有定义针对基类子对象的指定初始化语法。你既不能直接在派生类初始化列表里写基类的成员名,也不能通过类似
.Something{.DoesntWork = false}的写法指定初始化基类子对象,这种语法目前没有被标准采纳。 - 额外限制:C++要求指定初始化器的书写顺序必须和成员声明顺序完全一致,不允许乱序,也不支持跨嵌套层级混合指定成员。
可正常编译的基础用法示例
struct Something { bool Works; }; int main() { Something s = { .Works = false, }; }
无法通过标准合规编译的错误写法
struct Something { bool DoesntWork; }; struct Something2 : public Something { bool Works; }; int main() { Something2 s2 = { .Works = true, .DoesntWork = false, }; }
注意:个别编译器可能将该写法作为非标准扩展支持,但这类写法不具备跨编译器兼容性,不属于合规C++代码。
内容的提问来源于stack exchange,提问作者Nox
相关产品推荐
相关产品推荐

