在字段声明中使用 "struct Foo" 不会转发声明嵌套 class

use of "struct Foo" in field decl doesn't forward declare nested class

我显然误解了同时 "declaring" 和使用 struct X 引用类型的 C-ish 特性在 C++ 中是如何工作的。 (另外,我什至不知道这个功能叫什么,正确的。)我在下面有三个例子来展示我在做什么,但主要问题是:为什么嵌套类型在全局范围内以这种方式向前声明而不是在 class 范围内?

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) 为什么它以这种方式对 "declare" 类型 Impl 起作用,并且 b) 鉴于它起作用,为什么 Impl 在全局范围内而不是 class 范围内?

另外,顺便说一句,将字段声明为 auto_ptr<struct Foo2c::Impl> doesn't work either.

首先声明为 详细类型说明符 的名称的范围取决于它的使用方式。

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

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

详细规则见[basic.scope.cdecl]/7