如何转发声明内部类?

我有一个像这样的课程。

class Container {
public:
class 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

我怎样才能向前声明这个类,这样我就不必包含声明迭代器类的头文件?

114869 次浏览

这是根本不可能的。不能在容器外转发或声明嵌套结构。您只能在容器内转发声明它。

您需要执行以下操作之一

  • 使类成为非嵌套的
  • 更改声明顺序,以便首先完全定义嵌套类
  • 创建一个既可以在函数中使用又可以由嵌套类实现的公共基类。

我不相信在一个不完整的类上向前声明内部类是可行的(因为没有类定义,就没有办法知道内部类是否真的有)。因此,您必须包括容器的定义,以及一个向前声明的内部类:

class Container {
public:
class 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的,并且实现了export;))。