使用聚合公共基类(甚至多个聚合公共基类)会使类失去聚合类的优良属性是什么意思?
"聚合基类的定义"从 http://en.cppreference.com/w/cpp/language/aggregate_initialization http://en.wikipedia.org/wiki/C++_classes#Aggregate_classes
聚合类的好属性:
constexpr
s的文字类型。http://en.cppreference.com/w/cpp/language/aggregate_initialization#Example初始化的简要示例:
#include <string>
#include <array>
struct S {
int x;
struct Foo {
int i;
int j;
int a[3];
} b;
};
int main()
{
S s1 = { 1, { 2, 3, {4, 5, 6} } };
S s2 = { 1, 2, 3, 4, 5, 6}; // same, but with brace elision
}
另见: What are Aggregates and PODs and how/why are they special?
答案 0 :(得分:3)
根据http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3308.pdf
尽管标准有明确的意图,但B类不是文字类型:
struct A {}; struct B : A {};
这是因为它的构造函数在使用odr之前不会被隐式定义,直到那时它没有constexpr构造函数。
老实说,不确定这意味着什么。
答案 1 :(得分:2)
这是c ++ 11标准中聚合的定义,这是我所能提供的,而不是试图猜测委员会在做出这个决定时的想法。
1聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),非静态数据成员(9.2)没有大括号或相等的初始值,没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。
粗体表示聚合没有基类。
至于其他答案所带来的继承问题,您可以使用继承进行统一初始化工作。注意:A仍然是聚合。
struct A {
int val_A;
};
struct B : public A {
int val_B;
B(int a, int b) : A{a}, val_B(b) {}
};
int main() {
B b {2,3};
return 0;
}
你刚给B一个构造函数,IMO标准可以像默认一样轻松选择它。聚合物可能保留在原因中,因为它们符合以前的标准,但事实是c ++ 11的功能你真的不需要它们。实际上有一个问题是std::array
需要双括号,因为它没有初始化列表构造函数,我认为这个问题在c ++ 14中得到解决。
我想补充一点,鉴于统一初始化和初始化列表的新功能,我没有看到聚合添加到类的程度。
答案 2 :(得分:2)
由于具有公共、非虚拟基类的 C++17 类可以聚合。
struct Base1 {
int a, b;
};
struct Base2 {
int c;
};
struct Foo : Base1, Base2 {
int d, e;
};
struct Foo 的对象可以聚合初始化。以下初始化是等效的:
Foo foo {Base1{1, 2}, Base2{3}, 4, 5};
Foo foo {{1, 2}, {3}, 4, 5};
Foo foo {1, 2, 3, 4, 5};
答案 3 :(得分:0)
您如何初始化基类?
Derived d = {{1, 2}, 3, 4};
或
Derived d = {1, 2, 3, 4};
时
Derived d = {3, 4};
允许?
为了避免所有这一切,没有基类。