我有一堂这样的课...
class Container {
public:
class Iterator {
...
};
...
};
在其他地方,我想通过引用传递 Container::Iterator,但我不想包含头文件。如果我尝试转发声明该类,则会出现编译错误。
class Container::Iterator;
class Foo {
void Read(Container::Iterator& it);
};
编译上面的代码给出...
test.h:3: error: ‘Iterator’ in class ‘Container’ does not name a type
test.h:5: error: variable or field ‘Foo’ declared void
test.h:5: error: incomplete type ‘Container’ used in nested name specifier
test.h:5: error: ‘it’ was not declared in this scope
如何转发声明此类,这样我就不必包含声明 Iterator 类的头文件?
这根本不可能。您不能在容器外部转发声明嵌套结构。您只能在容器内转发声明。
您需要执行以下操作之一
我不相信在不完整的类上向前声明内部类有效(因为如果没有类定义,就无法知道是否确实存在is内部类)。因此,您必须在 Container 的定义中包含一个前向声明的内部类:
class Container {
public:
class Iterator;
};
然后在对应的源文件中,实现Container::Iterator:
class Container::Iterator {
};
然后仅包含容器标头(或者不用担心前向声明,只包含两者)
我知道没有办法完全按照你想要的方式做,但如果你愿意使用模板,这里有一个解决方法:
// Foo.h
struct Foo
{
export template<class T> void Read(T it);
};
// Foo.cpp
#include "Foo.h"
#include "Container.h"
/*
struct Container
{
struct Inner { };
};
*/
export template<>
void Foo::Read<Container::Inner>(Container::Inner& it)
{
}
#include "Foo.h"
int main()
{
Foo f;
Container::Inner i;
f.Read(i); // ok
f.Read(3); // error
}
希望这个习惯用法对您有用(希望您的编译器是基于 EDG 的并实现导出;))。