Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Использование общего кода в шаблонах


Автор: georain 1.8.2008, 15:05
У шаблонов есть эффект "раздувания" кода, часто его можно свести к минимуму специальным подходом в каждом случае. Интересует решение следующей проблемы:

Код

template <typename T>
class Derived: public Base<T>{    
    
    public: virtual void func(){
        // параметр T не используется
    };

};

Создает ли реальный компилятор по одному телу функции func() при каждом инстанциировании или все-же видит что зависимости от параметра T нету и делает одну?

Если создает несколько тел, то как можно обойти это "раздувание" (интересуют эффективные методы, без множественного виртуального наследования и введения дополнительного уровня косвенности)?

Автор: Daevaorn 1.8.2008, 15:18
Цитата(georain @  1.8.2008,  16:05 Найти цитируемый пост)
У шаблонов есть эффект "раздувания" кода, часто его можно свести к минимуму специальным подходом в каждом случае.

А лучше не думать об этом и доверится умному алгоритму мерджинга компилятора для таких случаев. Он лучше сделат это чем выsmile И архитектуру портить не придется.

Автор: Lazin 1.8.2008, 15:32
ф-я, неявно,  получает в качестве первого параметра указатель на экземпляр объекта, тип объекта будет отличаться при разных параметрах шаблона, соответственно это будут разные типы функций, даже если у них будет одинаковое тело...
но вообще соглашусь:
Цитата(Daevaorn @  1.8.2008,  15:18 Найти цитируемый пост)
Он лучше сделат это чем выsmile И архитектуру портить не придется. 


Автор: W4FhLF 1.8.2008, 15:40
Цитата(georain @  1.8.2008,  15:05 Найти цитируемый пост)
 все-же видит что зависимости от параметра T нету и делает одну?


Зависимость, или её отсутствие, от T недостаточное условие. Как минимум ещё должна отсутствовать зависимость от данных самого класса Derived. 

Автор: Earnest 4.8.2008, 11:23
Подумать насчет критичности. Если не очень, то не париться. Если есть подозрение, что критично, или очень душит жаба, или... то вынести общий код в нешаблонный базовый класс... работы не много, архитектура не сильно страдает, жаба успокаивается.

Автор: warmonger_ 4.8.2008, 17:21
Цитата(Daevaorn @  1.8.2008,  14:18 Найти цитируемый пост)
алгоритму мерджинга компилятора

Ой, а можно по подробнее?

Автор: Daevaorn 4.8.2008, 17:48
Цитата(warmonger_ @  4.8.2008,  18:21 Найти цитируемый пост)
Ой, а можно по подробнее? 

Компилятор в месте инстанцирования шаблона конкретным типом можешь осуществить мерджинг(слияние) кода, который сгенерирован для разных типов, но одинаков.

Автор: georain 4.8.2008, 19:26
Цитата(Earnest @  4.8.2008,  11:23 Найти цитируемый пост)
вынести общий код в нешаблонный базовый класс.

Тогда если функция в базовом нешаблонном класс inline, то получится тоже самое раздувание, а если не inline, то получится двойной вызов (функция то virtual, её не встроить). В этом суть проблемы smile

Добавлено через 7 минут и 44 секунды
Теоретически в машинном коде можно сделать чтобы в шаблоне была общая виртуальная функция (например указатель на одну и туже функцию в виртуальных таблицах), но как это написать на c++ никак не соображу.

Вопрос этот возник при объединении стратегий и полиморфных иерархий. 
(P.S. Пишу код критичный ко времени выполнения и размеру)

Автор: mes 4.8.2008, 21:42
Цитата(georain @  4.8.2008,  19:26 Найти цитируемый пост)
Тогда если функция в базовом нешаблонном класс inline, то получится тоже самое раздувание, а если не inline, то получится двойной вызов (функция то virtual, её не встроить). В этом суть проблемы

а бывает еше и третий случай?   smile 

Цитата(georain @  4.8.2008,  19:26 Найти цитируемый пост)
Теоретически в машинном коде можно сделать чтобы в шаблоне была общая виртуальная функция (например указатель на одну и туже функцию в виртуальных таблицах), но как это написать на c++ никак не соображу.

а то что Вы пытаетесь сейчас объяснить  не будет ли двойным вызовом ?   smile 

Цитата(georain @  4.8.2008,  19:26 Найти цитируемый пост)
 P.S. Пишу код критичный ко времени выполнения и размеру .

а вот виртуальный вызов всегда медленее чем обычный

Добавлено через 13 минут и 46 секунд
не это ли  имелoсь ввиду  при упоминании о виртуальной функции шаблона ?
http://www.insidecpp.ru/patterns/curiously_recurring_template_pattern/

Автор: georain 5.8.2008, 23:10
Цитата(mes @  4.8.2008,  21:42 Найти цитируемый пост)
а бывает еше и третий случай?

1) inline 2) не inline 3) другое архитектурное решение
Цитата(mes @  4.8.2008,  21:42 Найти цитируемый пост)
а то что Вы пытаетесь сейчас объяснить  не будет ли двойным вызовом ? 

нет, это будет вызов виртуальной функции, а не вызов функции из виртуальной функции
Цитата(mes @  4.8.2008,  21:42 Найти цитируемый пост)
а вот виртуальный вызов всегда медленее чем обычный

Спасибо!
Цитата(mes @  4.8.2008,  21:42 Найти цитируемый пост)
не это ли  имелoсь ввиду  при упоминании о виртуальной функции шаблона ?

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

Автор: mes 5.8.2008, 23:35
Цитата(georain @  5.8.2008,  23:10 Найти цитируемый пост)
1) inline 2) не inline 3) другое архитектурное решение


1 inline - кусок кода подставляется
2. не inline - кусок кода выделен как функция
3. другое архитектурное решение - это как ?!  smile   smile 


Цитата(georain @  5.8.2008,  23:10 Найти цитируемый пост)
нет, это будет вызов виртуальной функции, а не вызов функции из виртуальной функции

если так, то ив том случае будет просто вызов внешней функции, а не двойной




Цитата(georain @  5.8.2008,  23:10 Найти цитируемый пост)
Нет, к сожалению не это. CRTP позволяет использовать функциональность дочерних классов, а здесь необходимо иметь вызов одной виртуальной функции для семейства шаблонов. 

нельзя ли подробней , что Вы тут имели ввиду.. ? smile

Добавлено @ 23:44
Цитата(georain @  5.8.2008,  23:10 Найти цитируемый пост)
для семейства шаблонов

"семейство шаблонов" ?  интересно как Вы себе это представляете..

Если подразумеваете набор классов полученных из одного шаблона - то тогда скорей всего Вы не правильно представляете суть шаблона.
Шаблон это всего лишь макроподстановка  ( хоть и  облагороженная, и выведенная на новую ступень эволюции.. ) smile 

Автор: georain 6.8.2008, 17:49
Цитата(mes @  5.8.2008,  23:35 Найти цитируемый пост)
другое архитектурное решение - это как ?!

Это чтобы не пришлось решать inline тут нужна функция или не inline, для решения проблемы, а сделать вызов нужной функции в нужном месте, и решать inline или не inline в зависимости от её размера и к-ва точек вызова. Примером будет решение данного топика, если оно есть.

Цитата(mes @  5.8.2008,  23:35 Найти цитируемый пост)
если так, то ив том случае будет просто вызов внешней функции, а не двойной

в том? в каком?

Цитата(mes @  5.8.2008,  23:35 Найти цитируемый пост)
нельзя ли подробней , что Вы тут имели ввиду.. ?

То что написано в первом посте, пример и вопрос "как можно обойти "раздувание" без множественного виртуального наследования и введения дополнительного уровня косвенности?"

Цитата(mes @  5.8.2008,  23:35 Найти цитируемый пост)
Шаблон это всего лишь макроподстановка

Шаблоны - это революция в программировании. Сначала было структурное программирование, потом стало объектно-ориентированное,  добавился динамический полиморфизм, потом появилось обобщённое программирование, добавился статический полиморфизм, появилось метапрограммирование, а после ещё очень очень много всего. "Что нового можно сказать о языке C++? Оказывается очень много." Из предисловия к Современное проектирование на С++. Андрей Александреску.
А макроподстановка как была макроподстановкой из языка "с", так ей и остаётся.

Автор: mes 6.8.2008, 19:50
Цитата(georain @  6.8.2008,  17:49 Найти цитируемый пост)

Это чтобы не пришлось решать inline тут нужна функция или не inline, для решения проблемы, а сделать вызов нужной функции в нужном месте, и решать inline или не inline в зависимости от её размера и к-ва точек вызова. Примером будет решение данного топика, если оно есть.

именно это делает директива inline. Если она указана, то совсем не значит, что функция будет подставлена. Это всего лишь указание/подсказка для компилятора с линкером..

Цитата(georain @  6.8.2008,  17:49 Найти цитируемый пост)

в том? в каком?

в том где происходит вызов внешей функции.. например если вашу "витуальную " функцию заменить на обычную внешнюю

Цитата(georain @  6.8.2008,  17:49 Найти цитируемый пост)

То что написано в первом посте, пример и вопрос "как можно обойти "раздувание" без множественного виртуального наследования и введения дополнительного уровня косвенности?"

а чем виртуальная функция не дополнительный уровень косвенности ?
плюс к тому же виртуальная функция эта такая функция которая у каждого класса имеет свою реализацию
Вы же, насколько это следует из постов, виртуальной называете функцию имеюшую обшую реализацию для разных классов

Цитата(georain @  6.8.2008,  17:49 Найти цитируемый пост)
Шаблоны - это революция в программировании. 

никто не спорит


Цитата(georain @  6.8.2008,  17:49 Найти цитируемый пост)
начала было структурное программирование, потом стало объектно-ориентированное,  добавился динамический полиморфизм, потом появилось обобщённое программирование, добавился статический полиморфизм, появилось метапрограммирование, а после ещё очень очень много всего. "Что нового можно сказать о языке C++? Оказывается очень много." Из предисловия к Современное проектирование на С++. Андрей Александреску.

да согласен.. но это видимый результат .. А чем является шаблон по своей сути? 



Цитата(georain @  6.8.2008,  17:49 Найти цитируемый пост)
А макроподстановка как была макроподстановкой из языка "с", так ей и остаётся. 

шаблон , предпроцессор #define  и  внешняя кодогенерация являются разновидностью макроподстановки .

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)