c++ - C++20 中的指定初始化器
问题描述
我有一个关于 c++20 功能的问题,指定初始化程序(有关此功能的更多信息,请点击此处)
#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}};
}
-Wall -Wextra -std=gnu++2a
这段代码是用 gcc 9.2.0 和标志编译的。
正如您在上面看到的,结构Person
和Employee
都是聚合,但是Employee
使用指定的初始化程序无法初始化聚合。
有人可以解释一下为什么吗?
解决方案
根据 C++ 20 标准 (9.3.1 Aggregates. p. #3)
(3.1) — 如果初始化器列表是指定初始化器列表,则聚合应为类类型,每个指示符中的标识符应命名类的直接非静态数据成员,以及聚合的显式初始化元素是属于或包含这些成员的元素。
所以你不能使用指定的初始化列表来初始化基类的数据成员。
改用通常的列表初始化,例如
Employee e1{ "John", "Wick", 40, 50000 };
或者
Employee e1{ { "John", "Wick", 40 }, 50000 };
或者正如@Jarod42在评论中指出的那样,你可以写
Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };
在这种情况下,直接基类由指定的初始化器列表初始化,而整个类 Employe 由非指定的初始化器列表初始化。
推荐阅读
- firebase-hosting - 为什么 firebase deploy 命令不起作用?
- java - 使用springboot,如何访问异步方法中的存储库?
- sql - PostgresSQL - 返回表选择中的第一次出现
- r - Tidyr 与可选组分开
- spring-boot - 无法使用具有授权码的密钥斗篷的 Spring Cloud API 网关发出 POST 请求
- reactjs - 函数和数据未出现在 ContextProps 类型上。使用 TypeScript 反应上下文
- python - 如何使用 Poetry 查找特定软件包的可用版本列表?
- python - 具有行和列总和约束的二进制矩阵
- discord - 如何使用 python 获取不和谐服务器成员的完整列表?
- azure - 在验证通过后未启用 Azure 门户“创建”按钮中创建区块链成员