Форвардное объявление typedef в C ++

Почему компилятор не позволяет мне объявить typedef?

Предполагая, что это невозможно, какова наилучшая практика сохранения моего дерева включения?

9 Solutions collect form web for “Форвардное объявление typedef в C ++”

Вы можете выполнить форматирование typedef. Но делать

typedef AB; 

вы должны сначала направить объявление A :

 class A; typedef AB; 

Для тех из вас, как я, которые ищут вперед, объявляют структуру C-стиля, которая была определена с помощью typedef, в каком-то c ++-коде я нашел решение, которое выглядит следующим образом …

 // ah typedef struct _bah { int a; int b; } bah; // bh struct _bah; typedef _bah bah; class foo { foo(bah * b); foo(bah b); bah * mBah; }; // b.cpp #include "bh" #include "ah" foo::foo(bah * b) { mBah = b; } foo::foo(bah b) { mBah = &b; } 

В C ++ (но не просто C) вполне законно печатать тип дважды, если оба определения полностью идентичны:

 // foo.h struct A{}; typedef A *PA; // bar.h struct A; // forward declare A typedef A *PA; void func(PA x); // baz.cc #include "bar.h" #include "foo.h" // We've now included the definition for PA twice, but it's ok since they're the same ... A x; func(&x); 

Чтобы «fwd объявить typedef», вам нужно объявить class или структуру, а затем вы можете объявить тип typedef. Компилятор допускает несколько идентичных typedef.

длинная форма:

 class MyClass; typedef MyClass myclass_t; 

короткая форма:

 typedef class MyClass myclass_t; 

Поскольку для объявления типа необходимо знать его размер. Вы можете переслать объявление указателя на тип или typedef указатель на тип.

Если вы действительно этого захотите, вы можете использовать идиому pimpl, чтобы поддерживать включенность. Но если вы хотите использовать тип, а не указатель, компилятор должен знать его размер.

Редактировать: j_random_hacker добавляет важную квалификацию к этому ответу, в основном, что размер должен быть известен, чтобы использовать тип, но может быть сделано объявление вперед, если нам нужно только знать тип существует , чтобы создать указатели или ссылки на тип. Поскольку ОП не показывал код, но жаловался, что он не будет компилироваться, я предположил (возможно, правильно), что ОП пытался использовать этот тип, а не просто ссылался на него.

Использование форвардных деклараций вместо полного #include s возможно только тогда, когда вы не собираетесь использовать сам тип (в области этого файла), но указатель или ссылку на него.

Чтобы использовать сам тип, компилятор должен знать его размер – следовательно, его полная декларация должна быть видна – следовательно, необходим полный #include .

Однако размер указателя или ссылки известен компилятору, независимо от размера указателя, поэтому достаточно объявления прямого объявления – оно объявляет имя идентификатора типа.

Интересно отметить, что при использовании указателя или ссылки на типы class или struct компилятор может обрабатывать неполные типы, сохраняя при этом необходимость пересылать объявления также и типов указателей:

 // header.h // Look Ma! No forward declarations! typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere typedef class A& ARef; typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere typedef struct B& BRef; // Using the name without the class/struct specifier requires fwd. decl. the type itself. class C; // fwd. decl. type typedef C* CPtr; // no class/struct specifier typedef C& CRef; // no class/struct specifier struct D; // fwd. decl. type typedef D* DPtr; // no class/struct specifier typedef D& DRef; // no class/struct specifier 

У меня была такая же проблема, я не хотел связываться с несколькими typedefs в разных файлах, поэтому решил ее с наследованием:

был:

 class BurstBoss { public: typedef std::pair ParticleSystem; // removed this with... 

сделал:

 class ParticleSystem : public std::pair { public: ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair(system, enabled) { }; }; 

Работал как шарм. Конечно, мне пришлось изменить любые ссылки из

 BurstBoss::ParticleSystem 

просто

 ParticleSystem 

Как отметил Билл Коциас, единственный разумный способ сохранить данные typedef вашего персонажа в частном порядке, а вперед – объявить их с наследованием. Вы можете сделать это немного лучше с C ++ 11. Учти это:

 // LibraryPublicHeader.h class Implementation; class Library { ... private: Implementation* impl; }; 
 // LibraryPrivateImplementation.cpp // This annoyingly does not work: // // typedef std::shared_ptr Implementation; // However this does, and is almost as good. class Implementation : public std::shared_ptr { public: // C++11 allows us to easily copy all the constructors. using shared_ptr::shared_ptr; }; 

Как @BillKotsias, я использовал наследование, и это сработало для меня.

Я изменил этот беспорядок (который требовал всех заголовков boost в моей декларации * .h)

 #include  #include  #include  #include  #include  #include  #include  typedef boost::accumulators::accumulator_set> VanillaAccumulator_t ; std::unique_ptr acc; 

в эту декларацию (* .h)

 class VanillaAccumulator; std::unique_ptr acc; 

и реализация (* .cpp) была

 #include  #include  #include  #include  #include  #include  #include  class VanillaAccumulator : public boost::accumulators::accumulator_set> { }; 
  • C ++ шаблон typedef
  • массив фиксированной длины typedef
  • Разница между 'struct' и 'typedef struct' в C ++?
  • typedef указатель const weirdness
  • Почему мне нужно использовать typedef typename в g ++, но не VS?
  • Понимание typedefs для указателей функций в C
  • Являются ли typedef и #define одинаковыми в c?
  • Как вы читаете декларации C?
  • Interesting Posts

    Выход из Emacs очень медленный … Как устранить неполадки?

    Папка всегда становится доступной только для чтения. Даже когда я меняю его

    Как объединить несколько условий для подмножества кадра данных с помощью «ИЛИ»?

    Как удалить стандартную ассоциацию программ для типов файлов в Windows 7?

    Количество строк в файле с использованием партии

    Ручное резервное копирование драйверов

    jQuery: функция click исключает детей.

    Как удалить анимацию максимизации / минимизации окон в Win 7?

    Как программно сделать снимок экрана?

    Как применить несколько преобразований в CSS?

    Что представляет собой тип, за которым следует _t (underscore-t)?

    Преобразование значений RGB в название цвета

    Преобразование динамического диска в основной диск

    Раздел ext3 случайно монтируется только для чтения

    Обнаружение подписанного переполнения в C / C ++

    Давайте будем гением компьютера.