![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Alex007 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 29.12.2005 Репутация: нет Всего: нет |
Скажите, для чего нужны шаблоны в C++ и в кратце пожалуйста объясните их принцып действия,
а ато читая книги по С++ я так и не понял шаблоны |
|||
|
||||
| blackofe |
|
||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
допустим ты хочешь написать некую общую функцию сложения для разных типов аргументов, но тебе облом писать вот так:
ты используешь шаблон:
шаблоном ты не просто перекроешь реализацию предыдущих четырех функций, но и породишь множество потенциальных реализаций, лишь бы операции, проводимые над типами внутри функции, были легальными. к примеру, наш шаблон вполне можно использовать для string:
ну, и, конечно, самое главное, шаблоны могут быть помещены в библиотеку, и тебе не придется писать новую функцию f() для придуманных тобою типов, а всего лишь использовать имеющийся шаблон.
это что касается шаблонов функций. |
||||||||
|
|||||||||
| blackofe |
|
||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
шаблоны классов интереснее.
программа выведет:
потому что в первом случае инстанциирован класс для типа int. шаблоны классов часто используются для создания коллекций. такие коллекции могут содержать объекты достаточно произвольных типов, лишь бы эти типы отвечали определенным условиям (чаще всего имели определенными какие-либо операторы). как пример, стандартная библиотека с++ (ее еще называют stl - standard template library), построенная процентов на 90 на шаблонах, имеет шаблон vector. с его помощью можно построить коллекцию-вектор, допустим, int'ов, а можно string'ов, а можно любого другого пользовательского типа. и ко всем этим коллекциям можно применять общие операции добавления элемента, извлечения и пр. такой код:
выведет:
коллекции vi, vs, va содержат элементы разной природы, но работать с ними можно общими принципами. что, в общем-то, довольно удобно. |
||||||||
|
|||||||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
ИМХО, код немного неправильный, т. к если T!=int и T-пользовательский тип, будет попытка вызвать T::operator*(int), которого в T может не быть, т.е в общем случае код всегда работает правильно только для примитивных типов -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
MAKCim
+1. Здесь лучше применить специализацию шаблонов. Хотя и сам пример какой-то надуманный. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
| blackofe |
|
||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
не понял, что тут неправильного? проверка
сработает для любого типа T. и если T - не int, то мы перейдем к инструкции
имхо, никакого криминала. Добавлено @ 21:15
насчет надуманности согласен. однако пример был дан не как образец применения, а как образец написания. т.е. типа "что будет, если использовать шаблон?" и между прочим сам думал, какой бы пример придумать, чтобы было видно, что без шаблонов класса не обойтись. и кроме как для использования в коллекциях ничего путного не придумал (кстати, что ниже и продемонстрировал). в дебри типа ATL или WTL пускаться не хотелось. может быть, кто-нибудь из мэтров восполнит этот мой пробел? Это сообщение отредактировал(а) blackofe - 30.12.2005, 21:16 |
||||||||
|
|||||||||
| blackofe |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
и во-вторых, что значит неправильный? понятно, что шаблоны не всегда могут предусмотреть все варианты типов, с которыми эти шаблоны будут использоваться. даже та же stl этим грешит. и, имхо, это нормально. по поводу грешит. попробуй поместить в vector объектов объект, имеющий приватный конструктор копии.
ты получишь error C2248: 'A::A' : cannot access private member declared in class 'A'. другими словами, шаблон vector не работает "в общем случае". но ведь мы же не кричим при этом, что код стандартной библиотеки c++ "немного неправильный". |
||||
|
|||||
| Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
blackofe
Если T != int, то твой код в compile-time требует определенного T::operator *(int), хотя по логике программы он совсем не нужен. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
При инстанцировании класса компилятор проходит по всем веткам, а не
я говорил про это
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| Janus |
|
||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 186 Регистрация: 26.9.2005 Репутация: нет Всего: 1 |
У меня вопрос. Чем различаются вызовы из вышеприведенного примера:
И такой вызов:
Оба работают как и положено, так какая разница? Что лучше? --------------------
Проект "Репликатор" |
||||||||
|
|||||||||
| Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
В данном случае - никакая. Если вывод аргументов шаблона работает правильно, зачем писать больше? -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
| Janus |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 186 Регистрация: 26.9.2005 Репутация: нет Всего: 1 |
А когда будет разница? Зачем тогда нужна такая форма записи k = f<int>(1, 2);?
В одном учебнике такой формы нет вообще, а в другом написано, что функцию сначала надо объявить с конкретным указанием типа, а уже потом использовать... --------------------
Проект "Репликатор" |
|||
|
||||
| DeadSoul |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва Репутация: 2 Всего: 11 |
Иногда компилятор не в состояния "автоматом" определить тип аргумента.
выкинь эту книгу
это не функция. Это шаблон. Естественно, шаблон должен быть полностьь "виден" в месте использования -------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
||||||
|
|||||||
| LPBOY |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
Если вызвать так:
то будет ошибка - неоднозначность. Поэтому в этом случае надо уточнить
Или такой случай:
В функции f невозможно вывести тип параметра шаблона, а если уточнить f<int>, то все ok. --------------------
Каждый человек по-своему прав, а по-моему нет... |
||||||
|
|||||||
| Janus |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 186 Регистрация: 26.9.2005 Репутация: нет Всего: 1 |
LPBOY, спасибо, понял.
--------------------
Проект "Репликатор" |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |