![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Jcs |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 156 Регистрация: 1.10.2003 Репутация: нет Всего: нет |
Здравствуйте. Не работает код - хотелось бы выяснить причину.
Для простого случая
вызов
|
||||||
|
|||||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Вместо
пишите просто
Функции в C++ частично не специализируются, они просто перегружаются. А вообще, зачем это? Как я понимаю, вы параметризуете возвращаемый тип, но какова цель? Просто интересно... -------------------- ... |
||||
|
|||||
| Jcs |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 156 Регистрация: 1.10.2003 Репутация: нет Всего: нет |
Вообще, изначально в коде вместо temp был список типов, а функция параметризовалась интом, в зависимости от которого возвращался тип находящийся в списке на соответствующей позиции. Задача, для которой все это хочется использовать - извлечение по указателю необходимого типа. Т.е. функция принимает указатель на данные и, в зависимости от шаблонного инта, извлекает из памяти char, short, int и так далее и возвращает его. Перегрузка только по возвращаемому параметру невозвможна. Конечно, так как с помощью частичной специализации пока задача не решается, пришлось вывернуться при помощи перегрузки. Но интересна причина, почему этого не получается сделать. То ли я что-то не так делаю, то ли эта фигня еще не поддерживается компилятором, как например, шаблонные параметры функций по умолчанию.
|
|||
|
||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Просто код
сам по себе ошибочен: функция g не является частью шаблона, вы ведь используете только тип. Вот если вы сделаете ее частью шаблона, все будет OK. Что-то вроде этого:
Это сообщение отредактировал(а) Earnest - 21.6.2005, 20:23 -------------------- ... |
||||
|
|||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Вот еще вариант: разделяем код, чтобы специализировать только возвращаемые типы, тогда для "плоских" типов можно написать общий код, а уж для более сложных - специализировать:
-------------------- ... |
|||
|
||||
| Jcs |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 156 Регистрация: 1.10.2003 Репутация: нет Всего: нет |
Спасибо за идею. Еще немного о задаче. Есть хранилище данных, которое, к примеру считывается из файла, затем создаются сэмплы, каждый из которых знает адрес своих данных в этом хранилище. Сэмплы могут иметь разный размер. Поэтому есть класс базового сэмпла, который знает адрес своих данных и количество каналов (аудио данные, например) и от него наследуется параметризированный интом ребенок, который умеет извлекать данные в удобном для обработки виде. Работают они абсолютно одинаково, поэтому применение частичной специализации, и реализация функции извлечения данных по указателю привели бы к дублированию кода. Частичная специализация только метода извлечения невозможна, т.к. в данный момент это не поддерживается стандартом. Поэтому я хотел для извлечения использовать глобальную функцию, специализировав ее для каждого случая. Не получилось (почему - до сих пор не понимаю). Для решения, как мне кажется, проще привести частичную специализацию к перегрузке, чем заворачивать функцию в шаблонный класс (чтобы не плодить лишних классов). Чтобы избежать появления одинаковых типов параметров, (при 4 и 8 битах на канал возвращается unsigned char) можно использовать вспомогательный класс int2type. Тогда функция извлечения будет выглядеть так
Надо попробовать закомпилять частичную специализацию (а не перегрузку) функции в gcc. |
|||
|
||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Нельзя специализировать (перегружать функцию) только по возвращаемому типу. В одной из книг Страустроупа есть рассуждение об этом. Там приводятся различные проблемы, которые могли бы возникнуть, если включить перегрузку по возвращаемому значению. Частичной специализации функций в стандарте C++ нет, т.к. если бы она была, она делала бы тоже самое, что перегрузка. Ну посудите сами: перегрузка функции - это когда то же имя используется с другими типами/числом параметров. Короче, частичная специализация и перегрузка делают одно и то же.
Конечно, нормальное решение. Однако в клиентском коде все эти дополнительные параметры не очень уместны. Хочется сделать клиентский код как можно более прозрачным. И тут мы вспоминаем высказывание еще одного гуру (опять не помню кого, но кажется это был Майерс) - любую проблему в программировании можно решить добавлением еще одной прокладки в нужное место. Благодаря Страуструпу и его шаблонам, прокладки в C++ обходятся почти бесплатно (в смысле производительности). А лишние классы... Чего их экономить? При обобщенном программировании классы всегда плодятся как кролики. Но все это безобразие бесследно исчезает в момент компиляции... Если данные всегда извлекаются одинаково и меняется только длина, то конечно, разумно написать одну общую функцию, которая будет извлекать данные заданной длины. А из шаблонов вызывать ее с нужным параметром, inline. -------------------- ... |
||||
|
|||||
| Jcs |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 156 Регистрация: 1.10.2003 Репутация: нет Всего: нет |
Мне кажется, различия между перегрузкой и частично специализацией все-таки есть.
Данный код компиляется и вызывается нужная функция. Если же разремить перегурженные функции, тогда, естественно, компилятор не сможет определить, какую из версию overload_func вызвать. В случае специализации можно ему помочь)
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Хм... наверно, вы правы... в том что есть разница между специализацией и перегрузкой функций. Только это полная специализация, а не частичная.
-------------------- ... |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |