在字段decl中使用“struct Foo”不会转发声明嵌套类

时间:2016-06-08 20:54:10

标签: c++ scope nested forward-declaration

我显然误解了同时“声明”和引用使用struct X的类型的C-ish功能如何在C ++中工作。 (另外,我甚至不知道这个功能的名称是什么。)我在下面有三个例子来说明我在做什么,但主要的问题是:为什么在全球范围内以这种方式声明的嵌套类型而不是在课堂范围内?

This用于转发声明嵌套结构:

#include <memory>
class Foo1
{
    Foo1();
    ~Foo1();
    struct Impl;
    std::auto_ptr<Impl> m_pimpl;
};

struct Foo1::Impl
{
    Impl(){}
    ~Impl(){}
};

Foo1::Foo1(){}
Foo1::~Foo1(){}

int main() {}

所以现在我想通过使用半记忆的C功能保存几个字符,so see我删除了行struct Impl;,并且声明其类型为auto_ptr<struct Impl>的字段而不是auto_ptr<Impl>

#include <memory>
class Foo2a
{
    Foo2a();
    ~Foo2a();
    std::auto_ptr<struct Impl> m_pimpl;
};

struct Foo2a::Impl
{
    Impl(){}
    ~Impl(){}
};

Foo2a::Foo2a(){}
Foo2a::~Foo2a(){}

int main() {}

这里编译器抱怨no struct named 'Impl' in 'Foo2a'。果然,它在全球范围内,this编译:

#include <memory>
class Foo2b
{
    Foo2b();
    ~Foo2b();
    std::auto_ptr<struct Impl> m_pimpl;
};

struct Impl
{
    Impl(){}
    ~Impl(){}
};

Foo2b::Foo2b(){}
Foo2b::~Foo2b(){}

int main() {}

这是怎么回事? a)为什么它以这种方式“声明”类型Impl,并且b)鉴于它有效,为什么Impl在全局范围而不是类范围?

而且,BTW,将该字段声明为auto_ptr<struct Foo2c::Impl> doesn't work either

1 个答案:

答案 0 :(得分:2)

首先声明为 elaborated-type-specifier 的名称的范围取决于它的使用方式。

如果执行struct Impl;,则结构被声明为声明发生的任何范围的成员,如第一个示例中所示。但在任何其他上下文中,它在最近的封闭块或命名空间(但不是类)中声明,如第二和第三个示例中那样。

解决方案只是在任何其他用途之前在类中将其声明为struct Impl;。您可以在此之后将其称为Impl

有关详细规则,请参阅[basic.scope.cdecl] / 7.