Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126

Подстановка типа\шаблоны с++

14.05.2015, 17:21. Показов 5025. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, не могу разобраться
представим есть классец находится в .h

C++
1
2
3
4
5
6
7
8
9
10
enum MyEnum
{
enum1 = 0,
enum2 = 1
}
template<MyEnum param>
classMyClass
{
//и т.д начинка класс
};
класс большой

далее, есть предположим 2-3 .cpp файла, который тянут этот хедер с этим классом
в каждом .срр создается объект этого класса, причем в качестве шаблонного параметр всегда одно значение, пусть enum1
сколько раз происходит подстановка этого типа?
если несколько раз, то можно ли ускорить сборку? т.е сделать как то чтобы подстановка производилась 1 раз
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.05.2015, 17:21
Ответы с готовыми решениями:

Подстановка вычисляемого типа в шаблонах
Товарищи. Помогите разобраться с шаблонами. С шаблонами начал разбираться вчера, и потому излагаю задачу полностью, дабы не быть...

Шаблоны изменение типа
Передо мной стоит такая задача: class par1; class par2; class par3; class MyClass //Основной класс {

Шаблоны типа template<class T*>
Здравствуйте, объясните пожалуйста, что означает сия запись: template&lt;class T*&gt;. И означает ли она, что я далее смогу использовать только...

38
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 13:56
Студворк — интернет-сервис помощи студентам
Т.е. ты перенес инстанцирование класса в одну единицу трансляции, путем указания специализации для функции, которая создает его экземпляры по шаблону.
Функция инстанцироваться перестала вообще, а класс - теперь инстанцируется только в одном файле.
Если класс очень большой, то это дает выигрыш в скорости построения.
Но тем не менее, осталась проблема инстанцирования другими аргументами, отличными от enum1. В этом случае в отсутствие специализации, либо тела шаблона, будет ошибка линкера.
Если ты добавишь тело и прототип специализации как я показал в посте 7 в заголовочный файл, то не получишь замедления компиляции, но и корректность кода восстановишь.
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 13:56  [ТС]
вот и еще что вспомнил
если вместо сырого указателя
например
C++
1
auto_ptr<MyClass<enum1> >
так же неизбежно инстанциирование в каждом .срр
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 13:58
Цитата Сообщение от aLarman Посмотреть сообщение
class Derived : public MyClass<enum1>//явно тип указали
Инстанцирование будет при попытке создать объект Derived. Если создания объекта нет здесь, то и инстанцирования не будет. Не смотря на явную запись аргумента.
1
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 13:59  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Если класс очень большой, то это дает выигрыш в скорости построения.
Но тем не менее, осталась проблема инстанцирования другими аргументами, отличными от enum1. В этом случае в отсутствие специализации, либо тела шаблона, будет ошибка линкера.
я это понимаю, просто при компиляции набора .срр будет использоваться только один тип(MyClass<enum1>)
для другого набора .cpp будет сделана своя специализация
собсно цель - ускорить сборку, ибо тачка 32ядра, и хочется чтобы собиралось все поскорее(собсно .срр это файлы с gtest -ами)

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Инстанцирование будет при попытке создать объект Derived
кул
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 14:00
Цитата Сообщение от aLarman Посмотреть сообщение
так же неизбежно инстанциирование в каждом .срр
По правилам должно быть. Из-за деструктора, который требуется для delete. Но по факту это почти всегда можно оптимизировать, вынеся деструктор класса, в котором такой авто_птр сидит, в отдельный файл.
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 14:01  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Но по факту это почти всегда можно оптимизировать, вынеся деструктор класса, в котором такой авто_птр сидит в отдельный файл.
честно не совсем понял как это
auto_prt в .cpp же, как быть то?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 14:02
Цитата Сообщение от aLarman Посмотреть сообщение
auto_prt в .cpp же, как быть то?
Код покажи лучше А то может быть мы о разных вещах говорим.
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 14:05  [ТС]
ну из поста 10
было
C++
1
MyClass<enum1> * p = getNewInstance<enum1>();
сделать типо того

C++
1
2
std::auto_ptr<MyClass<enum1> > ptr;
ptr.reset(getNewInstatnce<enum1>());
Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Из-за деструктора, который требуется для delete.
вот незадача, получается если я сделаю так
в .срр
C++
1
2
3
MyClass<enum1> * p = getNewInstance<enum1>();
//поработали с указателем
delete p;
все таки произодйет инстанциирование?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 14:54
Цитата Сообщение от aLarman Посмотреть сообщение
все таки произодйет инстанциирование?
Да, как и в случае с использованием функций и переменных из этого класса. Но это не обязательно будет так. Компилятор может не генерировать инстанцию, если у него достаточно информации для этого.

Цитата Сообщение от aLarman Посмотреть сообщение
сделать типо того
В этом смысле нет разницы с примером без умных указателей.
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 15:06  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
В этом смысле нет разницы с примером без умных указателей.
т.е когда в качестве параметр для auto_ptr используется шаблонный класс то при инстанциировании auto_ptr типом MyClass<enum1>, cам класс не инстанциируется?

Добавлено через 6 минут
вобщем, нужна теперь конкретика
если я сделаю сырой указатель
то MyClass<enum1> * p- тут нет инстанциирования
если указатель инициализируется вызовом new то будет инстанциирование, т.к. тут уже пригодился конструкор класса
если иницилизировать указатель методом который дергает new и который определел в другой единице трансляции, то тут будет инстанциирование только один раз(в том месте где определн метод)
если я использую delete p то так же будет инстанциирование, т.к пригодился деструктор
если же сделать еще например метод который будет дергать delete то инстанциирование будет произведено там где определн этот метод(например в том же .срр что и getNewInstance)

если использовать auto_ptr, то опять же что получается
деструктор вызывается тут же(когда объект auto_ptr будет удаляться), его реализация нужна, тогда всегда будет происходить инстанциирование если использовать умный указатель
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 15:10
Цитата Сообщение от aLarman Посмотреть сообщение
т.е когда в качестве параметр для auto_ptr используется шаблонный класс то при инстанциировании auto_ptr типом MyClass<enum1>, cам класс не инстанциируется?
Внутри auto_ptr тот же самый указатель.
До тех пор, пока ты не дергаешь у него методы или не зовешь delete, то инстанцирования точно не будет.
Если например код такой:
C++
1
2
3
4
5
6
7
8
class Some
{
public:
   ~Some(); // определение в отдельном файле
 
private:
    std::auto_ptr< MyClass<enum1> > ptr;
};
То при подключении этого кода в другой файл и создание там объекта не приведет к инстанцированию MyClass<enum1>.
Вот это я имел в виду.
В случае, если ты используешь методы шаблона в данной единице трансляции, то инстанцирование будет.
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 15:13  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
В случае, если ты используешь методы шаблона в данной единице трансляции, то инстанцирование будет.
а если так вот создал я указатель
C++
1
MyClass<enum1> * p = getNewInstance<enum1>();
а потом где то
C++
1
p->someMethod()
то И В текущей единице трансляции будет произведено инстанциирование?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 15:26
aLarman, вообще тут надо внести ясность.
Говоря про необходимость или отсутствие необходимости инстанцирования нужно меть в виду, что компилятор в этом плане не должен следовать какому-то конкретному алгоритму (в стандарте есть кое-какие указания, но это скорее сглаживание углов, чем алгоритм "от и до"). Но он всегда исходит из того, чтобы генерировать как можно меньше. Поэтому везде выше, где я говорил, что инстанцирование будет, означает, что оно потенциально возможно, но это не значит, что оно будет в 100% случаев. Важно тут всего несколько вещей:
1) ODR не должно нарушаться, но если оно нарушится, то компилятор ничего про это не обязан говорить.
2) Компилятор не будет генерировать лишнего, если это возможно.

Цитата Сообщение от aLarman Посмотреть сообщение
то И В текущей единице трансляции будет произведено инстанциирование?
Если я правильно понял, то нет.
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 15:36  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Если я правильно понял, то нет.
просто уже не логично выходит, если нам нужен конструктор или деструктор(т.е дергаем new или delete) то вроде инстанциирование есть, а если конструктор и декструктор обернуть в методы, и реализовать их в другой единице трансляции то инстанциирование будет там, то почему тогда если дергаем другие методы(не конструктор и не деструктор) через указатель, то вроде и нет инстанциирования, честно, не сходится как то...
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 15:55
aLarman, Вот кое-какая информация насчет реализации инстанцирования в конкретных компиляторах.

Добавлено через 13 минут
Цитата Сообщение от aLarman Посмотреть сообщение
просто уже не логично выходит, если нам нужен конструктор или деструктор(т.е дергаем new или delete) то вроде инстанциирование есть, а если конструктор и декструктор обернуть в методы, и реализовать их в другой единице трансляции то инстанциирование будет там, то почему тогда если дергаем другие методы(не конструктор и не деструктор) через указатель, то вроде и нет инстанциирования, честно, не сходится как то...
Не сходится, потому что ты пытаешься все уложить в одну стратегию поведения.
Вот есть файл a.cpp и файл b.cpp, которые независимо подключают h с шаблоном.
Каждый файл совокупно с своими включаемыми файлами представляет собой единицу трансляции. Файлы компилируются независимо, естественно.
Теперь ты начинаешь работать с классом, в каждом из файлов. Ты вызываешь методы и т.п.
В общем виде, т.е. в той модели компиляции, которая считается основной в С++ (однопроходная компиляция), никак нельзя быть увереным, что соседний файл тоже использует этот класс. Следовательно нельзя положиться на то, что методы, которые мы тут используем, уже содержаться в объектном коде. Поэтому он генерирует и для этого файла и для того, а на этапе линковки убирает лишнее. Но тут возможно варианты. Современные компиляторы в принципе не обязаны поддерживать однопроходную модель компиляции и могут сперва собрать базу данных об использовании шаблонов, что позволит генерировать инстанцию сразу только в одном месте. Или можно использовать, например, предкомпилированные заголовки. Или собирать информацию об инстанциях в процессе компиляции. Или еще как. Это не регламентируется строго.
Теперь касаельно твоего недоумения.
В чем нелогичность? Ты передаешь указатель в функцию, которая неизвестно что делает: неизвестно что - для данной единицы трансляции, т.к. реализация находится в другой. Это не тоже самое, что позвать конкретный известный метод у шаблона. С учетом того, что компилятор не может знать без дополнительных ухищрений о том, что этот метод уже сгенерирован в другой единице трансляции.
1
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 16:35  [ТС]
собсно вывод какой?
C++
1
2
MyClass<enum1> * p  = getNewInstance<enum1>();//не вызывает инстанциирование
p->SomeMethod();//вызывает инстанциирование?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 16:44
Цитата Сообщение от aLarman Посмотреть сообщение
p->SomeMethod();//вызывает инстанциирование?
Да. Вызывает. Опять же в общем случае. Но может не вызывать для конкретной ситуации.
Например, если попытаться смоделировать тест, с функций класса, которая не касается состояния класса, а просто, например, выводит hello world на экран, то компилятор может не генерировать ничего, видя из контекста, что это ни к чему, и сразу вывести текст на экран, без промежуточных вызовов.
1
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
15.05.2015, 16:58  [ТС]
DrOffset, вот плохо что некоторые вещи все таки не однозначны, нельзя на что то положиться
а Вам спасибо за разъяснения
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
15.05.2015, 17:13
Цитата Сообщение от aLarman Посмотреть сообщение
DrOffset, вот плохо что некоторые вещи все таки не однозначны, нельзя на что то положиться
Нужно изучать как это сделано в конкретном компиляторе и делать выводы уже на основе этого.
В принципе очень просто сделать тест, на котором проявится все, что я выше говорил. Как в плюс, так и в минус.
Если тебе что-то не понятно, то рекомендую просто делать минитест и смотреть. Мне, например, удалось добиться как полной генерации всех инстанций во всех файлах, так и отсутствия генерации инстанций вообще. Даже в тех файлах, где объект класса создается. Просто меняя уровень оптимизации с -O1 на -O2. И это при том, что в примере функции вызываются у объекта.
Приготовил пример специально, если вдруг все равно было бы непонятно о чем я говорю
Можешь посмотреть во вложении.
Вложения
Тип файла: 7z test-tmpl.7z (1.5 Кб, 3 просмотров)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.05.2015, 17:13

Шаблоны. Ошибка приведения типа
Пишу курсовой проект. Шаблонную сортировку по всем полям для каждого класса. template&lt;class Type&gt; void...

Шаблоны, наследование и размер типа
Суть вопроса в том, что имея два шаблона класса, унаследованных от общего предка, и инстанциируя &quot;один другим&quot; имеем + n байт к...

Подстановка в выражение типа string
Имелось выражение, его с помощью convert переделали в string. Теперь я хочу отлавливать символ - степень(т.е. '^') и ту цифру, что стоит...

Подстановка типа в универсальный метод
Всем здравствовать. Вопрос: Можно ли в универсальном методе не указывать тип T явно, а подставлять вместо него некоторую переменную...

Подстановка, зависимые ячейки, подстановка по условию
Доброго времени суток. Предисловие! Можно не читать. Около недели назад начал разрабатывать решение для того чтобы упорядочить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru