C 20 中的指定初始化器:员工初始化之谜
C 20 的指定初始化器允许对被视为聚合的类进行精确的成员初始化。然而,当一个类继承自聚合基类时,就会出现问题,如提供的代码所示:
<code class="cpp">#include <iostream> constexpr unsigned DEFAULT_SALARY {10000}; struct Person { std::string name{}; std::string surname{}; unsigned age{}; }; struct Employee : Person { unsigned salary{DEFAULT_SALARY}; }; int main() { std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ? // For e2 compiler prints a warning "missing initializer for member 'Employee::<anonymous>' [-Wmissing-field-initializers]" Employee e2 {.salary{55000}}; }</code>
在这种情况下,Person 和 Employee 都被视为聚合,但 Employee 不能用指定的值进行初始化初始化器。解释在于 C 20 标准关于指定初始化器的规定:
根据 C 20 标准(9.3.1 聚合。第 #3 页),“如果初始化器列表是指定初始化器列表,聚合应为类类型,每个指示符中的标识符应命名该类的直接非静态数据成员。”
这意味着指定的初始化器只能初始化直接在类中声明的数据成员,而不能初始化从基类继承的成员。
因此,使用指定的初始值设定项作为 e1 来初始化 Employee 是不正确的。相反,必须使用通常的列表初始化:
<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 };</code>
或者,由于 Employee 直接继承自 Person,因此可以为基类使用嵌套的指定初始化器:
<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };</code>
This方法使用指定的初始化器正确初始化 Person 基类,同时为 Employee 类使用常规初始化器。
以上是指定初始化程序和继承:为什么我不能使用指定初始化程序初始化员工?的详细内容。更多信息请关注PHP中文网其他相关文章!