聚合 类 优于常规 类 的优势
Advantages of aggregate classes over regular classes
在我的用例中,我需要使用初始化列表初始化一个 class 变量。我了解到聚合 class 是一个 class,其中只有用户定义的数据成员。
聚合的优点是我们可以像这样使用初始化列表
struct fileJobPair {
int file;
int job;
};
fileJobPair obj = {10, 20};
但是如果我向它添加一个构造函数,class 将不再是一个聚合
struct fileJobPair {
int file;
int job;
fileJobPair() {
file = job = 0;
}
fileJobPair(int a, int b) {
file = a;
job = b;
}
};
但我看到我们对聚合 classes 的初始化列表优势仍然可以在这里使用。
fileJobPair obj = {10, 20};
所以我的问题是,如果常规 class 可以实现同样的事情,为什么我们还需要聚合。聚合的优势和实际用例是什么。
What are the advantages <...> of aggregates
不同于“通常”类,聚合类型:
- 已预定义“构造函数”(您的示例)
- 结构化绑定不需要类似元组的接口样板:
struct { int field1, field2; } aggregate;
auto&& [_1, _2] = aggregate;
- 有指定的初始值设定项:
Aggregate{.something = 42, .something_else = "whatever"};
也许还有其他我没有想到的事情。
What are the <...> real life use case of aggregates
例如多亏了#2,你可以在没有样板的情况下(反)序列化它们,另请参见 Boost.PFR。您可以轻松地合并它们(如元组)、“foreach”它们的字段等。
#3 的示例:用
替换大量的 Builder 模式代码
struct Foo {
struct Builder { std::string_view a, b, c; };
constexpr Foo(Builder); // TODO
} example{{.a = "cannot set a field twice", .c = "can skip fields"}};
the same thing can be acieved by regular class
如您所见,它不能或需要额外的样板文件。
在我的用例中,我需要使用初始化列表初始化一个 class 变量。我了解到聚合 class 是一个 class,其中只有用户定义的数据成员。
聚合的优点是我们可以像这样使用初始化列表
struct fileJobPair {
int file;
int job;
};
fileJobPair obj = {10, 20};
但是如果我向它添加一个构造函数,class 将不再是一个聚合
struct fileJobPair {
int file;
int job;
fileJobPair() {
file = job = 0;
}
fileJobPair(int a, int b) {
file = a;
job = b;
}
};
但我看到我们对聚合 classes 的初始化列表优势仍然可以在这里使用。
fileJobPair obj = {10, 20};
所以我的问题是,如果常规 class 可以实现同样的事情,为什么我们还需要聚合。聚合的优势和实际用例是什么。
What are the advantages <...> of aggregates
不同于“通常”类,聚合类型:
- 已预定义“构造函数”(您的示例)
- 结构化绑定不需要类似元组的接口样板:
struct { int field1, field2; } aggregate;
auto&& [_1, _2] = aggregate;
- 有指定的初始值设定项:
Aggregate{.something = 42, .something_else = "whatever"};
也许还有其他我没有想到的事情。
What are the <...> real life use case of aggregates
例如多亏了#2,你可以在没有样板的情况下(反)序列化它们,另请参见 Boost.PFR。您可以轻松地合并它们(如元组)、“foreach”它们的字段等。
#3 的示例:用
替换大量的 Builder 模式代码struct Foo {
struct Builder { std::string_view a, b, c; };
constexpr Foo(Builder); // TODO
} example{{.a = "cannot set a field twice", .c = "can skip fields"}};
the same thing can be acieved by regular class
如您所见,它不能或需要额外的样板文件。