我有一个类和一个const变量。
struct A
{
int b;
};
A const a;
班级A
是POD,可以像这样初始化。
A const a = { 3 };
恕我直言,拥有像这样的构造函数看起来很好。
struct A
{
int b;
A(int newB) : b(newB)
{
}
};
但Clang假定A
为非聚合类型。为什么我不能有这样的构造函数?或者我应该做些什么?
我修改了问题来表达我原来的意思。我错误地将struct
写为class
,并且抱歉@Johannes关于混淆:)
答案 0 :(得分:18)
POD
表示普通旧数据类型,根据定义,它不能具有用户定义的构造函数。
POD实际上是一种聚合类型(参见下一个引文)。什么是聚合? C ++标准在第8.5.1 / 1节中说明,
聚合是一个数组或类 (第9条)没有用户声明 施工人员(12.1),没有私人或 受保护的非静态数据成员 (第11条),没有基类(条款 10),没有虚函数(10.3)。
C ++标准的第9/4节说明,
[....] POD-struct是聚合类,没有非静态数据 非POD结构类型的成员, 非POD联合(或此类型的数组) 或引用,并且没有用户定义 复制分配运算符和否 用户定义的析构函数。同样,a POD-union是一个聚合联盟 没有类型的非静态数据成员 非POD结构,非POD结合(或 这类类型的数组)或引用,和 没有用户定义的副本分配 运营商和没有用户定义 析即可。 POD类是一个类 这是一个POD结构或一个 POD联合
从这一点来看,它也清楚POD类/ struct / union虽然也不能有用户定义的赋值运算符和用户定义的析构函数。
然而,还有其他类型的POD。 §3.9/ 10节说,
算术类型(3.9.1), 枚举类型,指针类型和 指向成员类型的指针(3.9.2)和 这些类型的cv限定版本 (3.9.3)统称为标量 类型。标量类型,POD结构类型, POD-union类型(第9节),数组 此类型和cv限定版本 这些类型(3.9.3)是 统称为POD类型。
阅读此常见问题解答:What is a "POD type"?
答案 1 :(得分:5)
A类是POD,可以像这样初始化
抱歉,这是错误的。由于b
是私有的,因此该类不是POD。
但Clang将A视为非聚合类型。为什么我不能有这样的构造函数?或者我应该做些什么?
这是目前存在的C ++限制。 C ++ 0x将不再具有此限制。虽然在C ++ 0x中您的类型也不是POD,但您的初始化将起作用(假设您创建了构造函数public
)。
(另外,我认为你在这里使用的更好的术语是“聚合”。使用{ ... }
的要求是你的类是聚合的。它不一定是POD)。
答案 2 :(得分:2)
其他答案很好地描述了POD规则。如果要为POD的构造函数获取类似的初始化样式,可以使用make_
样式函数,例如:
struct A
{
int i_;
};
A make_A(int i = 0)
{
A a = { i };
return a;
}
现在您可以获得初始化的POD实例,例如:
A a = make_A();