Aggregate
注意,有 bit fields 或者 有成员默认值 或者 有匿名 union 成员 也可以是 aggregate。
对含有 union 成员的聚合类使用 花括号 或 默认的全参数构造函数 初始化时,初始化的是 union 的第一个元素(不管 union 是不是匿名的)。
(C++20) 隐式提供的的全参数构造函数
#include <iostream>
#include <vector>
struct Point {
double x;
double y;
};
int main() {
std::vector<Point> points;
// 可以省略类型,花括号自动推导。
points.push_back({1, 1});
// 必须要写Point类型。因为是模板参数,捕获的时候不知道目的类型,不能推导。
points.emplace_back(Point{1, 1});
// 下面两行在 C++20 可以编译:
points.emplace_back(1, 2);
auto some_point = Point(1, 2);
}
注意这样的全参数构造函数是具有 explicit
属性的。所以下面的代码不能编译:
struct Id { int value; };
int main() {
Id some_id = 4;
}
作为模板的非类型参数?
不是所有的聚合类都能作为非类型参数!一个反例:定义了析构函数的聚合类不能作为 NTTP。
这是类类型模板非类型参数(C++ 20)引入后,部分聚合类 作为特殊情况享受到的一种好处。
结构化绑定?
不是所有的聚合类都能结构化绑定! 反例是含有匿名 union 成员的聚合类不能被结构化绑定。
部分聚合类也能够使用结构化绑定。见 结构化绑定(Structured Binding)。
struct Point {
double x{-1};
double y;
};
int main() {
auto [x, y] = Point{1.5, 2.0};
static_assert(std::is_aggregate_v<Point>); // true
}