C 20 中的指定初始化器:了解限制
在 C 20 中,指定初始化器提供了一种初始化聚合的特定成员的便捷方法。然而,这些初始化器有一定的局限性。
考虑提供的示例代码:
<code class="cpp">struct Person { std::string name{}; std::string surname{}; unsigned age{}; }; struct Employee : Person { unsigned salary{DEFAULT_SALARY}; }; int main() { Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // Possible Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // Error Employee e2{.salary{55000}}; // Warning }</code>
如代码所示,Person 和 Employee 都是聚合。但是,使用指定初始值设定项 (e1) 的 Employee 聚合初始化无法编译。为什么会这样?
答案在于 C 20 标准,特别是第 9.3.1 节聚合,第 3.1 点:
“如果初始化器列表是指定初始化器列表,则聚合应为类类型,每个指示符中的标识符应命名该类的直接非静态数据成员,并且聚合的显式初始化元素是那些成员或包含这些成员的元素。”
换句话说,指定初始化器只能用于初始化当前类的成员。它们不能用于继承成员或基类成员。这个限制就是为什么 e1 的初始化无效的原因。
要正确初始化 e1,可以使用常用的列表初始化语法:
<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 }; // Works</code>
或者,可以使用指定和非指定初始化器来实现相同的结果:
<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 }; // Also works</code>
在这种情况下,直接基类(Person)使用指定初始化器列表进行初始化,而整个 Employee 类使用非指定初始化器列表进行初始化初始化器列表。
总体而言,在使用 C 20 中的类层次结构时,记住指定初始化器的限制非常重要。通过使用适当的初始化语法,可以有效且准确地初始化基类和派生类的数据成员.
以上是为什么我不能使用指定的初始值设定项来初始化 C 20 中的继承成员?的详细内容。更多信息请关注PHP中文网其他相关文章!