Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Шаблоны и указатели на функции, логическая или синтаксическая проблема? 
:(
    Опции темы
Jcs
Дата 24.2.2004, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



Есть небольшая проблема:
имеет класс
Код
template<typename T,typename ALLOCATOR = CStdAllocator> class CListA
{
....
   class iterator
   {
   ....
   };
void Inject(const T& item,bool(*fcmp)(const iterator&,const iterator&) = &cmp_def);
};

имеем шаблонную функцию:
Код
template<typename T> bool cmp_def(const T& left,const T& right)
{if(left<=right)return true; return false;}


проблема - передать указатель на внешнюю функцию в Inject. Сначала я хотел определить явную реализацию функции cmp_def для T = const CListA<T>::iterator, но как это сделать - к сожалению не знаю. Для встроенных типов это сделать несложно

Код
template<> bool cmp_def<int>(const int& left,const int& right)
{...}

, но в случае итераторов получается вложенность шаблонов.

Второй вариант - написать отдельную функцию
Код
template<typename T> bool cmp_it(typename const CListA<T>::iterator& left,typename const CListA<T>::iterator& right)
{....}

Но тогда встают сразу две проблемы - нельзя задать функцию по умолчанию (если определить ее до класса, тогда не достучаться до итератора,т.к. класс еще не определен; если после - тогда не будет видно самой функции в классе). Но даже если отказаться от функции по умолчанию, то возникает проблема преобразования из 'bool (const CListA<T>::iterator&,const CListA<T>::iterator&)' в 'bool (__cdecl *)(const CListA<T>::iterator &,const CListA<T>::iterator&). Если кто ответит - буду очень признателен. Заранее спасибо.

PM   Вверх
FreshMeat
Дата 24.2.2004, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 30.1.2004

Репутация: нет
Всего: нет



Не мог бы ты описать логику работы класса (или хотя бы метода Inject)? Почему для вставки (?) элементов требуется сравнивать итераторы? Каким образом результат сравнения будет определять позицию нового элемента в контейнере?
PM MAIL   Вверх
FreshMeat
Дата 24.2.2004, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 30.1.2004

Репутация: нет
Всего: нет



Возможно тебе поможет следующий код (логика отсутствует, но т.к. задача не совсем понятна, больше написать ничего не могу)

Код

// ф-я может сравнивать все что угодно. единственное требование - наличие у класса T определенного оператора <= , ну и конструктора копирования конечно :)
template<typename T>
bool cmp_def( T left, T right )
{
   if ( left <= right )
       return true;
   return false;
}

template<typename T>
class CListA
{
public:
   class iterator
   {
   public:
       bool operator<=( iterator it ) const
       {
           return true;
       }
   };
   void Inject( T item, bool(*fcmp)( iterator, iterator ) = cmp_def<iterator> )
   {
       fcmp( iterator(), iterator() );
   }
};

int main()
{
   CListA<unsigned> list;
   list.Inject( 0 );
   list.Inject( 1 );
   list.Inject( 2 );
}

PM MAIL   Вверх
Jcs
Дата 24.2.2004, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



Класс CList - просто контейнер-список, а функция Inject используется для вставки конкретного итема в необходимую позицию отсортированного списки, к примеру если есть список 1,2,3,5, то 4 функция вставит перед 5) Для быстрого поиска реализован массив итераторов, которые очень похожи на обычные указатели. Т.е. сначала ищется место в таблице итераторов, а затем в самом списке. Массив итераторов просто хранит в себе прореженные значения списка ( с обвязками) и его назначение - увеличить быстродействие функции Inject. Поиск элемента в отсортированном массиве я тоже вынес в отдельный класс (шаблонный CSrtdData<T>), т.к. предполагается его часто использовать. Поиск ведется функцией-членом, которая принимает ссылку на шаблонный итем и указатель на функцию сравнения (find_index(const T& item,bool(*fcmp)(const T&,const T&)) ) Вот этот-то указатель я и не могу подсунуть (см. выше).
По умолчанию подсовывался указатель на cmp_def, но для сравнения итераторов их надо разименовать, т.е. алгоритм будет другим.
Для этого хотел определить отдельно cmp_def с типом константная ссылка на итератор, но не вышло. Такая вот хрень...
Огород конечно еще тот нагородил, но как по-другому - пока не знаю.
PM   Вверх
FreshMeat@Home
Дата 25.2.2004, 00:46 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











typedef std::multiset<T> CList?

Ассоциативные контейнеры (Associative containers)

Ассоциативные контейнеры обеспечивают быстрый поиск данных, основанных на ключах. Библиотека предоставляет четыре основных вида ассоциативных контейнеров: set (множество), multiset (множество с дубликатами), map (словарь) и multimap (словарь с дубликатами).

Все они берут в качестве параметров Key (ключ) и упорядочивающее отношение Compare, которое вызывает полное упорядочение по элементам Key. Кроме того, map и multimap ассоциируют произвольный тип T с Key. Объект типа Compare называется сравнивающим объектом (comparison object) контейнера.
http://www.rsdn.ru/article/cpp/stl.xml
  Вверх
Jcs
Дата 25.2.2004, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



Ссылка крутая, описание stl если где-то и есть то в основном в кастрированном виде, здесь все круто. И из ситуации вышел довольно просто - объявил еще одну шаблонную функцию для сравнения, которая предварительно разыменовывает свои параметры. Долбиться до итератора в этом случае не надо. А инстанцировать шаблонную функцию можно только для конкретного типа, например для

template<> bool cmp_def(const CListA<int>::iterator& left, const CListA<int>::iterator& right)
{...}, что в принципе логично. Спасибо за помощь.
PM   Вверх
mr.DUDA
Дата 25.2.2004, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Цитата
И из ситуации вышел довольно просто - объявил еще одну шаблонную функцию для сравнения, которая предварительно разыменовывает свои параметры. Долбиться до итератора в этом случае не надо

поздравляю, мы получили идею об "алгоритмах" из STL !

З.Ы. зачем реализовывать то, что уже сделано и не раз ?


--------------------
user posted image
PM MAIL WWW   Вверх
Jcs
Дата 26.2.2004, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



Во-первых алгоритм работы не совсем такой, как в STL (можно, конечно, использовать наследование, но все-таки хотелось бы знать как там все работает ), во-вторых - иногда проще написать свое, чем разобраться в чужом, а в третьих - во время написания таких базовых классов с изучением исходников STL можно понять и овладеть некоторыми навыками и приемами программирования.
PM   Вверх
bel_nikita
Дата 26.2.2004, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Jcs
ссылки про шаблоны
шаблоны1
шаблоны2
Может еще че-нить полезное обнаружишь
А есть классная книга: Д. Вандервуд, Н.М. Джосаттис "ШАБЛОНЫ С++. Справочник разработчика"
Советую приобрести. Куча полезной инфы по программированию. После этой книги, STL - отдыхает smile.gif

Это сообщение отредактировал(а) bel_nikita - 26.2.2004, 17:20


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
FreshMeat
Дата 26.2.2004, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 30.1.2004

Репутация: нет
Всего: нет



Цитата(Jcs @ 26.2.2004, 15:46)
Во-первых алгоритм работы не совсем такой, как в STL (можно, конечно, использовать наследование, но все-таки хотелось бы знать как там все работает ),

хочется знать - смотри исходники :)
Цитата

во-вторых - иногда проще написать свое, чем разобраться в чужом

код такого качества как стл? не проще.
не веришь? попробуй почитай Саттера "Решение сложных задач на С++", когда посмотришь на exception safety, останется махнуть рукой на собственные начинания :)
Цитата

а в третьих - во время написания таких базовых классов с изучением исходников STL можно понять и овладеть некоторыми навыками и приемами программирования.

можно. но иногда бывает очень сложно :). разработчики не оставляют в коде комментариев, по поводу архитектурных решений, поэтому можно легко впасть в заблуждение или просто не понять почему применяется тот или иной подход (особенно хитрые трюки можно просто не заметить :) )
может будет интересно www.stlport.org - одна из самых популярных и быстрых реализаций STL
Цитата(bel_nikita)

ссылки про шаблоны
www.boost.org

гы :) забавная формулировка :)
ценности ссылки это не отменяет :)
Цитата

А есть классная книга: Д. Вандервуд, Н.М. Джосаттис "ШАБЛОНЫ С++. Справочник разработчика"
Советую приобрести. Куча полезной инфы по программированию. После этой книги, STL - отдыхает 

Что значит СТЛ отдыхает?
2Jcs Если хочешь качественно разобраться с шаблонами, книга must have.
PM MAIL   Вверх
Jcs
Дата 26.2.2004, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



Насчет качества написания STL - я не претендую))) Ведь там крутые чуваки писали, которые у самых можно сказать истоков языка стояли. Но если читать описание (варианты которых, кстати, не отличаются подробным описанием используемых трюков и приемов), то далеко не уйдешь. Мне лично без практики простое изучение практически ничего не дает (у каждого свои методы). А где, как не в своих базовых классах я смогу попробовать увиденные приемы?.. Задачи, где это можно применить встречаются не так уж часто.. Пусть сначала получится класс-выродок, который спустя некоторое время кроме смеха ничего вызывать не будет, но как без этого?
Всех нюансов, конечно не постигнешь, по крайней мере, сразу.. Но по-моему лучше убить денек-другой на постигание приема, чем написать за эти пару дней сотни строк непрофессионального кода. А в STL приемов, наверное, хватит на все возможыне ситуации.. так что надо дерзать..
Спасибо за ссылки. Если не секрет, вы с STL разбирались, или просто использовали?
PM   Вверх
FreshMeat
Дата 3.3.2004, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 30.1.2004

Репутация: нет
Всего: нет



Цитата(Jcs @ 26.2.2004, 20:52)
Если не секрет, вы с STL разбирались, или просто использовали?

По мере необходимости разбирался, по большей части использую :) Если есть время и больше его нечем занять :), то можно и по интересным исходникам полазить...
Еще одна ссылка до кучи. http://www.rsdn.ru.
PM MAIL   Вверх
Fantasist
Дата 3.3.2004, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



А чем не подходит способ
Код
FreshMeat Дата 24.2.2004, 15:08
?



--------------------
Волны гасят ветер...
PM MAIL   Вверх
Jcs
Дата 4.3.2004, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



Тем, что cmp_def не разыменовывает итераторы перед сравнением. А инстанцировать cmp_def<T> для T = CListA<T,ALLOCATOR>::iterator я не смог, т.к. класс CListA сам шаблонный.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0834 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.