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

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

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

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?

4b9b3361

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

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

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

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

class Container {
public:
    class Iterator;
};

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

class Container::Iterator {
};

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

19
ответ дан 20 июня '09 в 18:09
источник

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

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

1
ответ дан 20 июня '09 в 18:11
источник