2009-06-20 89 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並實現出口;))。