为什么内联声明不是不完整的类型?

时间:2015-09-20 23:20:35

标签: c++ incomplete-type

请考虑以下代码:

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'具有不完整的类型,无法定义

1 个答案:

答案 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条。