聚合与非聚合 [=10=]
Aggregate vs non-aggregate structs/classes
我想了解聚合 class/struct/union 是什么:这里来自 C++ 标准:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
所以我写这个是为了测试:
struct NonAggregate{
virtual void f()const&{} // virtual member function makes the struct non-aggregate
};
struct Bar{}; // aggregate
struct X{}; // aggregate
struct Foo : Bar, X{
// Foo() = default; // if un-comment out makes Foo non-aggregate
Foo& operator =(Foo const&){return *this;} // ok
~Foo(){} // ok
int x_ = 0; // has an initializer. ? still aggregate?
Bar b_{}; // has an initializer. still aggregate?
private:
static double constexpr pi_ = 3.14;
};
double constexpr Foo::pi_; // definition needed- (although it has an in-class intializer) if Foo::pi_ used outside of the class
int main(){
std::cout << std::boolalpha << "Foo is an aggregate type: " << std::is_aggregate<Foo>::value << '\n';
}
输出为:
Foo is an aggregate type: true
那么为什么如果我默认合成的默认构造函数 Foo
不再是聚合?只要我没有提供用户自定义的?
标准还说:no base classes (Clause 10)
但我的结构继承自两个聚合结构 Bar
和 X
的乘积,但仍然是 n 聚合??!
标准说:no brace-or-equal-initializers for non-static data members (9.2)
但我有非静态数据成员的初始值设定项 x_
和 b_
但编译器仍然考虑 Foo
作为聚合结构??谢谢!
*P.S: 我用过 GCC 和 C++2a 标准
关于什么是聚合和什么不是聚合的规则在各种标准版本中发生了很大变化。这个答案简要地强调了与 OP 的三个问题相关的变化。有关更详尽的段落,请参见例如The fickle aggregate,其中介绍了这些不同的规则以及正确的标准(版本)参考。
So why If I default the synthesized default constructor Foo is no more an Aggregate? As long as I've not provided a user-defined one?
在 C++11 到 C++17 中,要求读取“无用户提供”的构造函数,这仍然允许 声明 构造函数,只要它们明确定义为-在第一次声明时默认或明确删除。
// Aggregate in C++11 through C++17. Not an aggregate in C++20.
struct A {
A() = default; // user-declared, but not user-provided
};
// Aggregate in C++11 through C++17. Not an aggregate in C++20.
struct B {
B() = delete; // user-declared, but not user-provided
};
// Never an aggregate.
struct C {
C(); // user-declared & user-provided
};
C::C() = default;
自 C++20 起,此要求对“无用户声明的构造函数”变得更加严格。
Also the standard says: no base classes (Clause 10) but my struct inherits multiply from two aggregate structs Bar and X but still n Aggregate??!
这是 C++11 和 C++14 中的规则。从 C++17 开始,它更加宽松:
1.4) no virtual, private, or protected base classes ([class.mi]).
The standard says: no brace-or-equal-initializers for non-static data members (9.2) but I have initializers for non-static data members x_ and b_ but the compiler still consider Foo as an aggregate struct?? Thank you!
此规则已在 C++14 中删除。
我想了解聚合 class/struct/union 是什么:这里来自 C++ 标准:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
所以我写这个是为了测试:
struct NonAggregate{
virtual void f()const&{} // virtual member function makes the struct non-aggregate
};
struct Bar{}; // aggregate
struct X{}; // aggregate
struct Foo : Bar, X{
// Foo() = default; // if un-comment out makes Foo non-aggregate
Foo& operator =(Foo const&){return *this;} // ok
~Foo(){} // ok
int x_ = 0; // has an initializer. ? still aggregate?
Bar b_{}; // has an initializer. still aggregate?
private:
static double constexpr pi_ = 3.14;
};
double constexpr Foo::pi_; // definition needed- (although it has an in-class intializer) if Foo::pi_ used outside of the class
int main(){
std::cout << std::boolalpha << "Foo is an aggregate type: " << std::is_aggregate<Foo>::value << '\n';
}
输出为:
Foo is an aggregate type: true
那么为什么如果我默认合成的默认构造函数
Foo
不再是聚合?只要我没有提供用户自定义的?标准还说:
no base classes (Clause 10)
但我的结构继承自两个聚合结构Bar
和X
的乘积,但仍然是 n 聚合??!标准说:
no brace-or-equal-initializers for non-static data members (9.2)
但我有非静态数据成员的初始值设定项x_
和b_
但编译器仍然考虑Foo
作为聚合结构??谢谢!
*P.S: 我用过 GCC 和 C++2a 标准
关于什么是聚合和什么不是聚合的规则在各种标准版本中发生了很大变化。这个答案简要地强调了与 OP 的三个问题相关的变化。有关更详尽的段落,请参见例如The fickle aggregate,其中介绍了这些不同的规则以及正确的标准(版本)参考。
So why If I default the synthesized default constructor Foo is no more an Aggregate? As long as I've not provided a user-defined one?
在 C++11 到 C++17 中,要求读取“无用户提供”的构造函数,这仍然允许 声明 构造函数,只要它们明确定义为-在第一次声明时默认或明确删除。
// Aggregate in C++11 through C++17. Not an aggregate in C++20.
struct A {
A() = default; // user-declared, but not user-provided
};
// Aggregate in C++11 through C++17. Not an aggregate in C++20.
struct B {
B() = delete; // user-declared, but not user-provided
};
// Never an aggregate.
struct C {
C(); // user-declared & user-provided
};
C::C() = default;
自 C++20 起,此要求对“无用户声明的构造函数”变得更加严格。
Also the standard says: no base classes (Clause 10) but my struct inherits multiply from two aggregate structs Bar and X but still n Aggregate??!
这是 C++11 和 C++14 中的规则。从 C++17 开始,它更加宽松:
1.4) no virtual, private, or protected base classes ([class.mi]).
The standard says: no brace-or-equal-initializers for non-static data members (9.2) but I have initializers for non-static data members x_ and b_ but the compiler still consider Foo as an aggregate struct?? Thank you!
此规则已在 C++14 中删除。