Почему компилятор не позволяет мне объявить typedef?
Предполагая, что это невозможно, как лучше сохранить дерево включения небольшим?
c++
typedef
forward-declaration
user96825
источник
источник
typedef
имена сложных многоуровневых типов шаблонов с использованием прямого объявления таким образом, являются довольно сложными и трудными. Не говоря уже о том, что это может потребовать углубления в детали реализации, скрытые в аргументах шаблона по умолчанию. И конечное решение - это длинный и нечитаемый код (особенно когда типы поступают из различных пространств имен), очень подверженный изменениям в исходном типе.Для тех из вас, кто, как я, желающих объявить структуру в стиле C, которая была определена с помощью typedef, в некотором коде c ++ я нашел решение, которое выглядит следующим образом ...
источник
Чтобы "fwd объявить определение типа", вам нужно объявить класс или структуру, а затем вы можете ввести определение типа. Множественные идентичные определения типов допустимы компилятором.
длинная форма:
короткая форма:
источник
В C ++ (но не в простом C) совершенно законно вводить тип дважды, если оба определения полностью идентичны:
источник
A
поля таким образом, посколькуA
он пуст по определению?Потому что, чтобы объявить тип, его размер должен быть известен. Вы можете перенаправить объявление указателя на тип или typedef указателя на тип.
Если вы действительно хотите, вы можете использовать идиому pimpl, чтобы уменьшить количество включений. Но если вы хотите использовать тип, а не указатель, компилятор должен знать его размер.
Редактировать: j_random_hacker добавляет важную квалификацию к этому ответу, в основном, что размер должен быть известен, чтобы использовать тип, но предварительное объявление может быть сделано, если нам нужно только знать, что тип существует , чтобы создать указатели или ссылки на тип. Поскольку OP не показывал код, но жаловался, что он не будет компилироваться, я предположил (вероятно, правильно), что OP пытался использовать тип, а не просто ссылаться на него.
источник
Использование предварительных объявлений вместо полных
#include
s возможно только в том случае, если вы не собираетесь использовать сам тип (в области действия этого файла), а указатель или ссылку на него.Чтобы использовать сам тип, компилятор должен знать его размер - следовательно, должно быть видно его полное объявление - следовательно, необходим полный
#include
.Однако размер указателя или ссылки известен компилятору независимо от размера указателя, поэтому достаточно предварительного объявления - оно объявляет имя идентификатора типа.
Интересно, что при использовании указателя или ссылки на
class
илиstruct
типов, компилятор может обрабатывать неполные типы, избавляя вас от необходимости также объявлять типы pointee:источник
У меня была та же проблема, я не хотел связываться с несколькими определениями типов в разных файлах, поэтому я решил ее с помощью наследования:
был:
сделал:
Работал как шарм. Конечно, мне пришлось изменить любые ссылки с
просто
источник
Я заменил
typedef
(using
если быть точным) наследованием и наследованием конструктора (?).оригинал
Заменены
Таким образом, я смог переслать объявить
CallStack
с:источник
Как отметил Билл Коциас, единственный разумный способ сохранить подробности typedef вашей точки и объявить их вперед - это наследование. Вы можете сделать это немного лучше с C ++ 11, хотя. Учти это:
источник
Как и @BillKotsias, я использовал наследование, и оно работало на меня.
Я изменил этот беспорядок (который требовал все заголовки повышения в моем объявлении * .h)
в эту декларацию (* .h)
и реализация (* .cpp) была
источник