Ку!
Люди, есть шаблон (к примеру MyCoolTemplate) с функциональностью покруче StringStream-а. Есть несколько единиц трансляции (к примеру a.cpp и b.cpp), в каждой из которых есть переменная типа MyCoolTemplate<int> и с ней что-то делается. Вопрос
1. Код реализации MyCoolTemplate<int> (реализация функций этого класса) будут присутствовать в обоих obj-файлах? Подозреваю, что да. И, соотв. вопрос №2
Как избежать дублирования кода? Т.е. я хочу, чтобы реализация функциональности MyCoolTemplate<int> во всем проекте была только одна. Как этого добиться?
Re: Шаблоны и дублирование кода.
От:
Аноним
Дата:
13.03.06 13:36
Оценка:
Здравствуйте, Аноним, Вы писали:
А>1. Код реализации MyCoolTemplate<int> (реализация функций этого класса) будут присутствовать в обоих obj-файлах? Подозреваю, что да.
Именно так. Однако линкер в выходном exe-file оставит только одно инстанциирование MyCoolTemplate<int>. Из какого obj, Стандартом не специфицировано, и зависит от производителя компилятора
А>Как избежать дублирования кода? Т.е. я хочу, чтобы реализация функциональности MyCoolTemplate<int> во всем проекте была только одна. Как этого добиться?
использовать директиву явного инстанциирования
template class MyCoolTemplate<int>;
в какой-либо ОДНОЙ единице трансляции
В идеале вы можете организовать ваш проект из трех файлов
1. MyCoolTemplate.h — только объявление шаблона
2. MyCoolTemplate_def.h — определение функций членов и инициализация статических дата членов (если они есть). Этот неадер должен включать предыдущий
3. MyCoolTemplate_inst.cpp — включает предыдущий неадер + директиву явного инстанциирования. Этот файл добавляется в ваш проект
4. Все пользовательские cpp-файлы теперь могут использовать только MyCoolTemplate.h. Понятное дело вам будут доступны только конкректные типы полученные явным инстанциированием в MyCoolTemplate_inst.cpp
К примеру MyCoolTemplate<int> — ОК, MyCoolTemplate<double> — ошибка линковки "чего то там не определено"
Здравствуйте, Аноним, Вы писали:
А>1. Код реализации MyCoolTemplate<int> (реализация функций этого класса) будут присутствовать в обоих obj-файлах? Подозреваю, что да.
Здравствуйте, Аноним, Вы писали:
А>Ку! А>Люди, есть шаблон (к примеру MyCoolTemplate) с функциональностью покруче StringStream-а. Есть несколько единиц трансляции (к примеру a.cpp и b.cpp), в каждой из которых есть переменная типа MyCoolTemplate<int> и с ней что-то делается. Вопрос А>1. Код реализации MyCoolTemplate<int> (реализация функций этого класса) будут присутствовать в обоих obj-файлах? Подозреваю, что да. И, соотв. вопрос №2 А>Как избежать дублирования кода? Т.е. я хочу, чтобы реализация функциональности MyCoolTemplate<int> во всем проекте была только одна. Как этого добиться?
А зачем это надо-то? Чего страшного?
Практически вся стандартная библиотека построена на шаблонах и ничего.
Hello, remark!
You wrote on Wed, 15 Mar 2006 10:28:30 GMT:
А>> Ку! А>> Люди, есть шаблон (к примеру MyCoolTemplate) с функциональностью А>> покруче StringStream-а. Есть несколько единиц трансляции (к примеру А>> a.cpp и b.cpp), в каждой из которых есть переменная типа А>> MyCoolTemplate<int> и с ней что-то делается. Вопрос 1. Код реализации А>> MyCoolTemplate<int> (реализация функций этого класса) будут А>> присутствовать в обоих obj-файлах? Подозреваю, что да. И, соотв. вопрос А>> №2 Как избежать дублирования кода? Т.е. я хочу, чтобы реализация А>> функциональности MyCoolTemplate<int> во всем проекте была только одна. А>> Как этого добиться?
r> А зачем это надо-то? Чего страшного?
Ну-у-у-у... Бывает так что размеры объектных файлов библиотеки раздувается очень даже неприлично. А все потому что очень классный темплейт раскручивается в каждой единице трансляции. И в итоге имеем метров 300 объектников только для одной dll-ки коих в проекте может быть с десяток. И когда это хозяйство начинает линковаться.... тушите свет. А путем нехитрый плясок с инстанцированием этого матерего шаблона удается уменьшить размеры объектников на порядок, что очень сильно сказывается на времени сборки и соответственно на настроении собирающего
Здравствуйте, remark, Вы писали:
R>А зачем это надо-то? Чего страшного? R>Практически вся стандартная библиотека построена на шаблонах и ничего.
Страшно тем, что link потом очень сильно озабочен выкидыванием дупликатов
и всевозмозными мерджами. По крайней мере линкер от MS очень тормозит.
С точки зрения теории конечно это все мелочи,
но на практике получается очень неприятный эффект от использования шаблонов.
Здравствуйте, Аноним, Вы писали:
А>Люди, есть шаблон (к примеру MyCoolTemplate) с функциональностью покруче StringStream-а. Есть несколько единиц трансляции (к примеру a.cpp и b.cpp), в каждой из которых есть переменная типа MyCoolTemplate<int> и с ней что-то делается. Вопрос А>1. Код реализации MyCoolTemplate<int> (реализация функций этого класса) будут присутствовать в обоих obj-файлах? Подозреваю, что да. И, соотв. вопрос №2 А>Как избежать дублирования кода? Т.е. я хочу, чтобы реализация функциональности MyCoolTemplate<int> во всем проекте была только одна. Как этого добиться?
В объектниках-то он может быть и будет присутствовать в обоих, но в финальном выполняемом файле будет только одна копия. Линкер будет обязан позаботиться о том, чтобы фактически использовалась только одна копия хотя бы потому, что это требование имеет определенное отражение в спецификации языка.
Когда говорят о дублировании кода, вызываемом шаблонами, имеют в виду дублирование, вызываемое специализациями с разными аргументами, как, например, 'MyCoolTemplate<int>' и 'MyCoolTemplate<double>'. Для одинаковых специализаций такой проблемы обычно нет.
В любом случае, это в том числе и вопрос качества реализации. Лучше проверь сначала, существует ли проблема, а потом уж будешь решать ее, если понадобится.
Best regards,
Андрей Тарасевич
Re[2]: Шаблоны и дублирование кода.
От:
Аноним
Дата:
16.03.06 10:09
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Здравствуйте, Аноним, Вы писали:
А>>Люди, есть шаблон (к примеру MyCoolTemplate) с функциональностью покруче StringStream-а. Есть несколько единиц трансляции (к примеру a.cpp и b.cpp), в каждой из которых есть переменная типа MyCoolTemplate<int> и с ней что-то делается. Вопрос А>>1. Код реализации MyCoolTemplate<int> (реализация функций этого класса) будут присутствовать в обоих obj-файлах? Подозреваю, что да. И, соотв. вопрос №2 А>>Как избежать дублирования кода? Т.е. я хочу, чтобы реализация функциональности MyCoolTemplate<int> во всем проекте была только одна. Как этого добиться?
АТ>В объектниках-то он может быть и будет присутствовать в обоих, но в финальном выполняемом файле будет только одна копия. Линкер будет обязан позаботиться о том, чтобы фактически использовалась только одна копия хотя бы потому, что это требование имеет определенное отражение в спецификации языка.
АТ>Когда говорят о дублировании кода, вызываемом шаблонами, имеют в виду дублирование, вызываемое специализациями с разными аргументами, как, например, 'MyCoolTemplate<int>' и 'MyCoolTemplate<double>'. Для одинаковых специализаций такой проблемы обычно нет.
Нет, я говорил именно для одинаковых шаблонов. Дублирование кода в случае разных аргументов — это другая проблема. Я знаю, что _в_общем_виде_ она не решается (если бы решалась — уже бы решили, т.к. проблема достаточно серьезна), а для частных случаев существуют частичные специализации. Я, правда, пока "не умею их готовить", но это уже другая тема.
АТ>В любом случае, это в том числе и вопрос качества реализации. Лучше проверь сначала, существует ли проблема, а потом уж будешь решать ее, если понадобится.
Спасибо всем, успокоили. Я действительно не проверил "существует ли проблема", просто исходил из простых логических рассуждений (типа откуда компилятору знать, что в другой единице трансляции он уже сгенирировал код для этого шаблона? Про линкер я не подумал). В любом случае обсуждение оказалось полезным — чем плохо решение с тремя файлами (CoolTemplate.h CoolTemplate_def.h и CoolTemplate_instances.cpp)? Автору +1 (жалко анонимы ставить оценки не могут).
Re[2]: Шаблоны и дублирование кода.
От:
Аноним
Дата:
16.03.06 10:11
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>В объектниках-то он может быть и будет присутствовать в обоих, но в финальном выполняемом файле будет только одна копия. Линкер будет обязан позаботиться о том, чтобы фактически использовалась только одна копия хотя бы потому, что это требование имеет определенное отражение в спецификации языка.
В догонку к предыдущему сообщению — а как "это требование имеет определенное отражение в спецификации языка"?