简体   繁体   English

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

[英]Why an inline declaration is not an incomplete type?

Consider the code below: 请考虑以下代码:

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;
}

It compiles fine under at least 2 compilers (gcc5.2, clang3.5). 它在至少2个编译器(gcc5.2,clang3.5)下编译得很好。 My question is: 我的问题是:

  • Why isn't Bar considered an incomplete type in the constructor Foo::Foo , as I forward-declare it above the constructor but fully use it inside the constructor? 为什么Bar在构造函数Foo::Foo不被认为是一个不完整的类型,因为我在构造函数上面将它转发声明但在构造函数中完全使用它?

Whenever I move Foo::Bar outside the class, in other words Bar becomes a stand-alone class, I get the expected 每当我在课外移动Foo::Bar ,换句话说Bar成为一个独立的类,我得到了预期

error: aggregate 'Foo::Bar bar' has incomplete type and cannot be defined 错误:聚合'Foo :: Bar bar'的类型不完整,无法定义

Within the member specification the class is considered complete within function bodies, from the draft C++ standard section 9.2 [class.mem] : 在成员规范中,该类在函数体中被认为是完整的,来自草案C ++标准第9.2[class.mem]

A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier. 在类说明符的结束时,类被认为是完全定义的对象类型(3.9)(或完整类型)。 Within the class member-specification, the class is regarded as complete within function bodies , default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes). 在类成员规范中,该类在函数体 ,缺省参数,引入继承构造函数(12.9)的使用声明,异常规范和非静态数据成员的括号或等于初始化器中被视为完整 (包括嵌套类中的这类东西)。 Otherwise it is regarded as incomplete within its own class member-specification 否则,它在其自己的类成员规范中被视为不完整

Which means you don't even have to forward declare Bar ( see it live ): 这意味着你甚至不必转发声明Bar现场直播 ):

struct Foo {
    Foo()
    {
        Bar bar; 
    }
    struct Bar {};  
};

Forward declaring could be useful in avoiding violation of section 3.3.7 paragraph 2 and 3 . 前瞻性声明可能有助于避免违反第3.3.7第2和第3款

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM