9-5 指定初始化(C++20)

9.5 指定初始化

​ 为了提高数据成员初始化的可读性和灵活性,C++20标准中引入了指定初始化的特性。该特性允许指定初始化数据成员的名称,从而使代码意图更加明确。

struct Point
{
int x;
int y;
}

Point p{.x = 4, .y = 3}; //指定初始化语法

1. 指定初始化的要求

1.1 对象必须是一个聚合类型

​ 如果对象不是聚合类型(即存在自定义给构造函数),则不能使用指定初始化。所以,一般采用默认成员初始值的方式来使用。

struct Point3D
{
int x = 100;
int y = 100;
int z = 100;
}

Point3D p{.z = 3}; //x = 100, y = 100, z = 3
1.2 指定的成员必须是非静态成员

​ 静态成员属于整个类,不能被指定。

1.3 每个成员只能被初始化一次
Point p{.y = 100, .y = 100};		//报错
1.4 成员初始化必须按照声明顺序进行

​ 与C语言不同,C++中的成员初始化必须按照声明的顺序。

struct Point3D
{
int x = 100;
int y = 100;
int z = 100;
}

Point3D p{.z = 3, .x = 5}; //C++编译失败,C语言编译成功
1.5 联合体中的成员只能指定一个

​ 联合体公用一个空间,所以只能指定一个进行初始化。

union u
{
int a;
const char* b;
};

u f = {.a = 1};
u g = {.b = "asdf"};
u h = {.a = 1, .b = "asdf"}; //编译失败,同时指定多个成员
1.6 不能嵌套指定初始化成员

​ C语言中可行,C++中禁止

struct Line
{
Point a;
Point b;
}

Line l{.a.y = 5}; //错误
Line l{.a{.y = 5}}; //正确
1.7 不能和其它类型的初始化混用
Point p{.x = 2, 3};		//错误
1.8 处理数组,不能指定元素

​ 和C语言不一样,因为在C++中与lambda表达式冲突

int arr[3] = { [1] = 5 };	//错误