Как я могу объявить внутренний класс?

Возможный дубликат:
Переслать декларацию вложенных типов/классов в С++

У меня такой класс...

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?

Ответ 1

Это просто невозможно. Вы не можете переслать объявление вложенной структуры вне контейнера. Вы можете только переслать объявление в контейнер.

Вам нужно будет сделать одно из следующих

  • Сделать класс не вложенным
  • Измените свой порядок объявлений так, чтобы вложенный класс был полностью определен первым.
  • Создайте общий базовый класс, который может использоваться как в функции, так и реализован вложенным классом.

Ответ 2

Я не верю, что декларирование внутреннего класса в неполном классе выполняется, потому что без определения класса нет способа узнать, действительно ли есть внутренний класс). Поэтому вам нужно будет включить определение Container с объявленным вперед внутренним классом:

class Container {
public:
    class Iterator;
};

Затем в отдельном заголовке реализуем Container:: Iterator:

class Container::Iterator {
};

Затем # включить только заголовок контейнера (или не беспокоиться о форвардном объявлении и просто включать оба)

Ответ 3

Я не знаю, как сделать то, что вы хотите, но вот обходной путь, если вы хотите использовать шаблоны:

// 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 и реализует экспорт;)).