Упреждающее объявление (forward declaration) для шаблонных классов |
Здравствуйте, гость ( Вход | Регистрация )
Упреждающее объявление (forward declaration) для шаблонных классов |
daorus |
31.10.2010, 0:00
Сообщение
#11
|
Студент Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: 0 |
Да все просто на самом деле Круто. Огромное спасибо!==== Раз уж тут чисто по синтаксису вопрос задал. Есть один вопрос, не знаю где спросить. Вот грядет стандарт С+. Там есть лямбды, т.е. функции без сигнатур. А они вообще в кути могут хоть какую-то полезную нагрузку нести или эти лямбды - это просто "с боку бантик"? Сорри за оффтопик, есличо. |
|
|
Litkevich Yuriy |
31.10.2010, 0:45
Сообщение
#12
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
daorus, лучше следовать правилу:
Одна проблема (вопрос) - одна тема. Так потом проще искать, если приспичит |
|
|
Iron Bug |
31.10.2010, 11:08
Сообщение
#13
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
Какой синтаксис форвад-декларации для типа хеш, если я хочу в классе хранить на него указатель а где в приведённом коде форвард-декларация-то? форвард-декларацией называется случай, когда класс ссылается сам на себя или на потомков. ну и всё сказанное (насчёт указателей) тогда справедливо. но в примере никакой форвард-декларации нет. обычное использование шаблонного класса. стандартного инклюда должно хватить. главное, если компилить под вендой, с MSVC, то нельзя выносить реализацию шаблонного класса из его объявления (это баг MSVC, несовместимость со стандартами). то есть, в заголовочнике должен быть весь класс и заголовочник должен быть указан до использования где-либо в коде. Сообщение отредактировал Iron Bug - 31.10.2010, 11:09 |
|
|
Litkevich Yuriy |
31.10.2010, 11:30
Сообщение
#14
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
|
|
|
Алексей1153 |
31.10.2010, 11:34
Сообщение
#15
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
то есть, в заголовочнике должен быть весь класс и заголовочник должен быть указан до использования где-либо в коде. о да. Столкнулся несколько раз, пытался решить, спрашивал советы - так и оставил в заголовочнике весь шаблон. Но душа то не удовлетворена ))) Изворачивался-таки, разделял шаблон на шаблонную составляющую и обычную. Последняя составляющая обычно гораздо объёмнее шаблонной, так что оно того стОило Для разделения применялись все нечестные приёмы: преобразование указателя к void* , указатель на коллбэк, так же преобразованный к void*, а где надо - приводимый к нужному указателю |
|
|
daorus |
31.10.2010, 11:55
Сообщение
#16
|
Студент Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: 0 |
Iron Bug, во-первых, привет земляку. Я тоже из Екатеринбурга.
Цитата но в примере никакой форвард-декларации нет Форвард-декларация - это такой способ сэкономить время на компилции. Форвард декларация - это простое сообщение о существовании сигнатуры. А декларация - это подробное разъяснение, что за этой сигнатурой скрывается. Форвард-деклараци - это любая функция или класс, в синтаксисе которых отсутствуют фигурные скобки - это основной признак форвад-декларации. Исторически появились как необходимость кросс-вставки классов.
Ну а сегодня, её юзают тупо для сокращения времени компиляции, если есть возможность обойтись одними указателями на класс или функцию, потому что размер указателя вне зависимости от типа есть константа.
Топик начался с того, что для шаблонных классов создание обычной декларации не катит, а как катит я не знал. И тут мне на форуме подсказали супер-мегафичу, которую я домыслил и оказалось, что для шаблонов форвард-декларацией является как бы создание экземлпяра шаблона! + кстати, подсказанный пример можно существенно сократить, выкинув сигнатуры классов в шаблоне KEY, T. Главное - сохранить кол-во классов в шаблоне.
|
|
|
Iron Bug |
31.10.2010, 12:08
Сообщение
#17
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
Исторически появились как необходимость кросс-вставки классов. воот. так что кроме ссылок на самого себя и циклических ссылок это, конечно, можно, но нафиг нигде не нужно. ибо всё,что нужно компилеру - это увидеть описание класса до его использования в коде, что, в случае простого использования класса, достигается вставкой инклюда в одном месте кода, как правило в заголовочнике, где он используется. а в обычном случае, без циклических ссылок, предварительные объявления без инклюда, тем более для стандартно или библиотечно определённых шаблонов, ни к чему, кроме ещё одного лишнего прохода при компиляции, не приводят. куда ты его вставишь - дело десятое. если класс сам по себе используется, то компилятор обработает его один раз. так что "экономия" времени компиляции будет только в случае библиотеки, которая оперирует только указателями и никогда не обращается к самому классу. о да. Столкнулся несколько раз, пытался решить, спрашивал советы - так и оставил в заголовочнике весь шаблон. я как-то тоже напоролась на это. это баг мелкософта. об этом написано где-то в MSDN, только мелким-мелким шрифтом на страничке, которую так просто и не найти там порядка восьми несовместимостей со стандартом у них имеется. в прочих компилерах этого нет. Топик начался с того, что для шаблонных классов создание обычной декларации не катит, а как катит я не знал. И тут мне на форуме подсказали супер-мегафичу, которую я домыслил и оказалось, что для шаблонов форвард-декларацией является как бы создание экземлпяра шаблона! + кстати, подсказанный пример можно существенно сократить, выкинув сигнатуры классов в шаблоне KEY, T. Главное - сохранить кол-во классов в шаблоне. всё объясняется проще: когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. это и есть баг компилера, его несоответствие стандарту. просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован, либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта. Сообщение отредактировал Iron Bug - 31.10.2010, 12:25 |
|
|
Алексей1153 |
31.10.2010, 12:52
Сообщение
#18
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
экономия времени будет. По крайней мере в студии это очень заметно
Например, класс A (не шаблон), описанный в хедере, не используется в некоем cpp, но из-за вложенности хедеров попал в начало этого cpp. Компилятор его лишний раз скомпилирует (потому что это только у шаблонов не компилируется неиспользыемое). В случае же разнесения кода по A.h и A.cpp , компиляция пройдёт шустрее, так как компилироваться класс A будет всего один раз. Проверить можно так: пусть класс A целиком сидит в A.cpp Можно написать в любой его функции строчку
Везде, где инклуд A.h используется, предупреждение появится (ровно столько же раз, сколько заинклужено) |
|
|
igor_bogomolov |
31.10.2010, 13:34
Сообщение
#19
|
Профессионал Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: 29 |
с MSVC, то нельзя выносить реализацию шаблонного класса из его объявления (это баг MSVC, несовместимость со стандартами). то есть, в заголовочнике должен быть весь класс так и оставил в заголовочнике весь шаблон При чем здесь MSVC? Разделить реализацию и объявление шаблона можно только с использованием ключевого слова export, которое ни один компилятор так и не реализовал. Поэтому для шаблонов подходит только модель включения, т.е. в одном файле должны быть все объявления и определения шаблона. У Вандевурда & Джосатиса это хорошо описано.template<class, class> b; // шаблонный форвард Тут ошибка, должно быть template<class, class> class b;Кстати, по поводу того зачем нужны форвард объявления хорошо описано в этой книге (ссылка) (см. раздел 2.3) --Добавлено чуть позже-------------------------------------------------------------------------- Этого вообще не понял всё объясняется проще: когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. это и есть баг компилера, его несоответствие стандарту. просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован, либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта. Разберем по частям Цитата когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. совершенно правильно считаетЦитата просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован а как вы собираетесь использовать класс, если в данном листе трансляции ничего про него не известно? Естественно нужно делать инклуд, и шаблоны тут не при чемЦитата либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта какой еще фиктивный объект? Где вы его увидели? Там лишь форвард объявление шаблонного класса, никаких объектов не создается
|
|
|
daorus |
31.10.2010, 13:47
Сообщение
#20
|
Студент Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: 0 |
достигается вставкой инклюда в одном месте кода У меня почему-то активное использование форвардов существенно экономит время компиляции. + если зависимость от форварда, то изменение в заголовочном файле не генерит флаг на перекомпиляцию. А вообще это просто вопрос привычки. Привык я форвары в хедерах юзать вместо инклудов. :-)всё объясняется проще: когда мелкософтовский компилер а я на g++ работаю. Про msvc вообще ничего не знаю.Тут ошибка, должно быть template<class, class> class b; Да, конечно. Я слишком увлекся идеей. Но почему-то у меня нет кнопки правка сообщений, поэтому баг так и останется висеть в моем посте. :-(с использованием ключевого слова export Если я правильно понял, это вы уже не про хедеры, а про форварды в *.cpp файлах? т.е. типа такого
Вы это имели ввиду? |
|
|
Текстовая версия | Сейчас: 21.12.2024, 19:13 |