在字段声明中使用 "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
我显然误解了同时 "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