2009-06-20 138 views
120

可能重复:
Forward declaration of nested types/classes in C++如何转发声明内部类?

我有一类这样的...

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 

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

回答

102

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

你需要做以下

  • 一个使类非嵌套
  • 更改声明顺序,使嵌套类是完全定义的第一
  • 创建一个共同的基类它既可以在函数中使用,也可以由嵌套类实现。
+2

通用基类是我最终使用最多的解决方案。 – Coyote 2013-10-03 12:49:27

+0

如果需要,您可以使用朋友来解决此问题。 – 2016-06-14 16:32:46

18

我不相信前宣布内部类的一个未完成的工程类(因为没有类的定义,也没有办法知道是否有实际一个内部类)。所以,你必须包括集装箱的定义,以正宣布内部类:

class Container { 
public: 
    class Iterator; 
}; 

然后,在一个单独的头,实现集装箱:迭代:

class Container::Iterator { 
}; 

随后的#include只有容器头部(或不担心向前声明,只是包括)

1

我知道没有办法做的正是你想要的,但这里是一个解决办法,如果你愿意使用模板:

// 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并实现出口;))。