请考虑以下代码:
struct Foo {
struct Bar;
Foo()
{
Bar bar; // Why isn't Bar an incomplete type?!
}
struct Bar {}; // Full definition
};
// struct Bar {}; // fails to compile due to incomplete type
int main()
{
Foo foo;
}
它在至少2个编译器(gcc5.2,clang3.5)下编译得很好。我的问题是:
Bar
在构造函数Foo::Foo
中被认为是一个不完整的类型,因为我在构造函数上方将其前向声明但在构造函数中完全使用它? 每当我在课堂外移动Foo::Bar
时,换句话说Bar
成为一个独立的课程,我得到了预期的
错误:聚合' Foo :: Bar bar'具有不完整的类型,无法定义
答案 0 :(得分:8)
在成员规范中,从C ++标准草案部分9.2
[class.mem] 草案中,该类在功能体内被认为是完整的:
一个类被认为是一个完全定义的对象类型(3.9)(或 完成类型)在类说明符的结束时。 内 class member-specification,该类被认为是完整的 函数体,默认参数,引用的使用声明 继承构造函数(12.9),异常规范和 用于非静态数据成员的括号或等于初始化器(包括 嵌套类中的这类东西)。否则它被认为是不完整的 在其自己的类成员规范
中
这意味着您甚至不必转发声明Bar
( see it live ):
struct Foo {
Foo()
{
Bar bar;
}
struct Bar {};
};
转发声明可能有助于避免违反第3.3.7 paragraph 2 and 3条。