Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Visual C++/MFC/WTL > Компиляция заголовочных файлов |
Автор: IOnic 13.12.2005, 02:28 |
Вопрос: имплементация шаблонных функций (членов классов) в .h файле влечет за собой включение тела функции (а не ссылки на нее) в бинарнике? Если нет, то применимо ли "inline" для того чтобы компилятор включал тело функции-члена шаблонного класа? (среда VS2003) Невероятных размеров спасибо! |
Автор: Earnest 13.12.2005, 19:13 |
1) Инстационируется только то, что реально вызывается. 2) Все остальное - то же, что для нешаблонных классов, т.е. напишешь inline - будет inline, нет - будет только одно тело где-нибудь (в пределах исполняемого модуля). Если хочешь экспортировать шаблонную функцию из DLL, это надо делать явно. |
Автор: Guest 13.12.2005, 19:35 |
Earnest Подскажи, как шаблонную функцию включить в dll ? |
Автор: IOnic 13.12.2005, 20:50 | ||
... насчет этого я в курсе. А вот есть ли разница между имплементацией в .h и в .cpp с точки зрения бинарника? Другими словами, равносильна ли имплементация функции добавлению "inline" к этой функции в .cpp? Пример - stdlib: std::vector, std::pair, и т.д. Там все в .h. Вобщем не только из-за этого есть подозрения. Я видел кучу исходников в которых небольшие шаблонные классы были полностью в .h в отличии от "тяжелых" (те же параметры шаблонов). Так что вопрос остается открытым... |
Автор: Earnest 13.12.2005, 20:54 | ||
Шаблонную функцию в DLL не включишь, только ее конкретную реализацию для конкретных параметров.
Извини, видимо, ввела тебя в заблуждение неточной фразой. Имела в виду, что шаблонную функцию для каких-то параметров можно явно инстационировать в каком-то модуле заранее. |
Автор: Earnest 13.12.2005, 21:05 | ||||
Разница в том, что тела шаблонных функций, написанные в cpp, недоступны для других частей программы, а, стало быть, бесполезны как общедоступные шаблоны. Конечно, никто не мешает включить cpp файл директивой #include, но мы ведь не об этом говорим? ![]() Реализация шаблонов в cpp-файлах имеет смысл в двух случаях: 1) класс совершенно локальный, и используется ровно в том модуле, где нарисован. 2) шаблоны достаточтно тяжелые для засовывания в Н-файл (например, много связей тянут), но заранее известно, что они будут использоваться только с заданным небольшим числом параметров. Тогда их нужно явно инстационировать для этих параметров.
нет, если функция не имплементирована прямо внутри объявления класса. |
Автор: IOnic 13.12.2005, 21:05 |
айайай... я чуток загнул ![]() |
Автор: Earnest 13.12.2005, 21:12 |
Так, я уже не понимаю, чего ты не понимаешь... ![]() |
Автор: IOnic 13.12.2005, 21:13 | ||
Вот оно! Тоесть, ДА, если мы определяем название функции, типы аргументов, и сразу же за этим пишем тело??? |
Автор: Earnest 13.12.2005, 21:17 |
... то это инлайн. Ну ты и спрашиваешь! ![]() Добавлено @ 21:17 Если, конечно, оно не виртуал... |
Автор: IOnic 13.12.2005, 21:24 | ||
тоесть инлайн не используя кейворд "инлайн". Это меня и интересовало (я не проф. прогаммер, даже на курсы не ходил, и в Страуструпе насчет этого ничего не нашел). Сенкс! ![]() Добавлено @ 21:25
![]() Earnest спасибо! |
Автор: threef 14.12.2005, 14:32 |
Инлайн функции либо обьявляются inline, либо записываются в тело класса. При этом, если в ней присутствуют циклы, статические переменные, рекурсия, switch или в программе есть применение адреса этой функции, то компилятор не сделает ее inline. Зато может сделать другую, при указании на оптимизацию по скорости и учитывая ограничения выше. inline никак не связаны с шаблонами. Прекомпиляция заголовков снижает затраты на проверку синтаксиса и вставку файлов. Шаблоны компилируются только для конкретных параметров, поэтому они и "плавают" в заголовочных файлах целиком - шаблон не может быть откомпилирован в виде шаблона и в таком виде помещен в библиотеку. Это, наверное, и есть причина того, что в MS VS удобнее использовать "родные" MFC-классы коллекций, чем коллекции STL. |
Автор: Earnest 15.12.2005, 08:26 | ||||
Это не совсем так. Т.е., конечно, для таблицы виртуальных функций или аргумента-указателя на функцию генерируется "тело", но в местах прямого вызова, если связывание статическое, вполне может быть выполнена inline-подстановка. Так что даже виртуальные функции стоит делать inline (если они короткие): по крайней мере вызов типа base_class::function внутри перекрытого метода будет инлайн.
Вот уж странное заявление. Если кому и удобнее использовать MFC-коллекции, так только в силу привычки и нежелания отказываться от хорошо знакомого. STL-коллекции имеют более естественную семантику (взять хотя бы эти уродские псевдоитераторы MFC GetPrevPos\GetNextPos), они гибче и уж конечно "стандартнее". |
Автор: Гость_Medved 16.12.2005, 22:22 |
Подскажите чайнику. Пишу программу на Microsoft Visual Studio . NET Professional 2003 : #include <iostream> int main() { cout << "Hello.\n"; return 0; } Вот какую ошибку он выдает : unable to start debbuging. unable to start programm 'c\documents and settings\...\мои документы\visual studio progects\1\debug\1.exe' |
Автор: threef 20.12.2005, 11:14 | ||||||
При чем здесь виртуальные функции ? Если обьект "с " будет статическим, то компилер сделает функцию A::next встроенной; как только появляется использование указателя на функцию, будь то статический вызов или через динамический обьект - тело функции обязательно появится. Чем не статический вызов ?
|
Автор: Earnest 20.12.2005, 15:44 | ||
Статический или динамический объект - не важно, ты путаешь. Я говорила о статическом связывании, т.е. связывании времени компиляции - в противоположность связыванию run-time. Если сделать твой пример (вызов функции по указателю) более реальным (разнести в коде присвоение и вызов), будет связывание run-time - т.к. непосредственно в точке вызова нельзя определить какая функция будет вызвана в момент компиляции. |
Автор: threef 20.12.2005, 19:40 |
Конкретно в моем примере связывание статическое ? |
Автор: Earnest 21.12.2005, 08:07 |
Формально - нет (вызов по указателю). Но оптимизатор может сообразить, что указателю только что присвоили адрес конкретной функции, и подставить прямой вызов. (Честно говоря, не знаю - есть ли реально такая оптимизация.) Но не в этом суть: одна и та же функция (в т.ч. виртуальная) может вызываться как статически, так и динамически. В первом случае, если она объявлена инлайн, может быть выполнена подстановка, во втором - нет. |
Автор: threef 24.12.2005, 10:12 |
Очень хотелось бы узнать, у кого такой умный оптимизатор. WATCOM? FARLAP ? Intel ? А пример кода есть ? Я имею в виду откомпилированный+MAP. |