Russian Qt Forum

Программирование => С/C++ => Тема начата: Rotten_c от Сентябрь 02, 2012, 19:36



Название: Проблема с шаблонами
Отправлено: Rotten_c от Сентябрь 02, 2012, 19:36
Есть шаблон
Код:
template <class T, class U> // Т потомок U
class GameObjMemCell
{
vector<U*> Objects;
typename vector<U*>::iterator Iteree;
public:
GameObjMemCell() //пустой
~GameObjMemCell() //удаляет объекты и освобождает выделенную память
void init(int numOfObjs) //выделяет блок памяти под numOfObjs и создает их там
int freeObjsNum() //возвращает число свободных объектов
U* GetObject() //отдает указатель на базовый класс U, который указывает на самом деле на отбъект типа T (грустно так делать, но надо мне)
bool RetObject(U*); //"забирает" объект по указателю, если может и возвращает true, иначе false
};
   Пишу такой велосипед, чтобы была возможность "создавать" в игре пачку объектов поодиночке без обращений к ОС каждый раз когда нужен один объект.
   
   Инстанцированные GameObjMemCell укладываются в std::list
   для работы с которыми есть шаблонная функция
   
Код:
	template <class T, class U>
U* MemoryCellsManager::takeObject(
list< GameObjMemCell<T,U> > ObjGiver, //лист с GameObjMemCell ячейками
binary_function<GameObjMemCell<T,U>, GameObjMemCell<T,U>, bool> Sorter, //функтор для сортировки
int& initsize)
{
/*некоторый код*/
ObjGiver.sort(Sorter); //вот этот вызов вызывает ошибку компиляции
/*некоторый код*/
}
   
error C2064: term does not evaluate to a function taking 2 arguments   

Лог построения тут: http://pastebin.com/PrCQ6uK9

код который вызывает ошибку

Код:
template<class _Pr, class _Ty1, class _Ty2> inline
bool _Debug_lt_pred(_Pr _Pred,
_Ty1& _Left, _Ty2& _Right,
_Dbfile_t _File, _Dbline_t _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
if (!_Pred(_Left, _Right)) //тут
return (false);
else if (_Pred(_Right, _Left)) //и тут
_DEBUG_ERROR2("invalid operator<", _File, _Line);
return (true);
}

для упорядочивания задается предикат:
Код:
template <class T, class U>
class sortByFreeObjs_less:public binary_function<GameObjMemCell<T,U>, GameObjMemCell<T,U>, bool>
{
public:
bool operator() (GameObjMemCell<T,U> a, GameObjMemCell<T,U> b)
{ return  a.freeObjsNum() < b.freeObjsNum(); };
};

Если я убираю сортировку
Код:
ObjGiver.sort(Sorter);
, код компилится. Не понимаю в чем дело, вроде бы предикат написан правильно.


Название: Re: Проблема с шаблонами
Отправлено: sergey_ulyanov от Сентябрь 03, 2012, 08:54
Посмотрите на объявление std::binary_function: там присутствуют только определения синонимов для аргументов и результата, но нет определения никакого operator, который требуется для выполнения сравнения элементов списка при сортировке.


Название: Re: Проблема с шаблонами
Отправлено: Igors от Сентябрь 03, 2012, 09:12
Я понимаю что задача несложная, но с "магией шаблонов" понять становится мудрено  :) Во всяком случае функтор лучше сделать константным
Код
C++ (Qt)
bool operator() (const GameObjMemCell<T,U> & a, const GameObjMemCell<T,U> & b) const
 
И изучать в отладчике место вылета, возможно сам контейнер испорчен


Название: Re: Проблема с шаблонами
Отправлено: andrew.k от Сентябрь 03, 2012, 10:36
И изучать в отладчике место вылета, возможно сам контейнер испорчен
Какой же отладчик, если оно не компилится?


Название: Re: Проблема с шаблонами
Отправлено: Igors от Сентябрь 03, 2012, 14:49
Какой же отладчик, если оно не компилится?
Ага, точно, то я попутал (запуганный лесом template  :))

Не наблюдаю оператора () у самого binary_function, вижу только у порожденного (который здесь ни при чем)


Название: Re: Проблема с шаблонами
Отправлено: Rotten_c от Сентябрь 03, 2012, 21:27

Не наблюдаю оператора () у самого binary_function, вижу только у порожденного (который здесь ни при чем)
sergey_, Igors,
Основываясь на  (C++ Reference (http://www.cplusplus.com/reference/std/functional/binary_function/))
Цитировать
Binary function object base class
This is a base class for standard binary function objects.

Generically, function objects are instances of a class with member function operator() defined. This member function allows the object to be used with the same syntax as a regular function call, and therefore it can be used in templates instead of a pointer to a function.

Тоесть у объекта есть оператор(), который позволяет использовать его как функцию. И оттуда же пример кода
Код
C++ (Qt)
struct Compare : public binary_function<int,int,bool> {
 bool operator() (int a, int b) {return (a==b);}
};
Другое дело, что я не правильно его использую. В итоге заменил функтор шаблонной функцией, все собралось.
К сожалению, так и не понял, что нужно было сделать, чтобы заработало через функтор, ведь это по сути близко к функции.
Если кто-нибудь объяснит в чем моя ошибка, буду очень благодарен.

Спасибо всем, кто откликнулся.


Название: Re: Проблема с шаблонами
Отправлено: Igors от Сентябрь 03, 2012, 22:11
Тоесть у объекта есть оператор(), который позволяет использовать его как функцию. И оттуда же пример кода
У порожденного класса - есть, но у Вас же тип Sorter = binary_function<..> а у нее нет


Название: Re: Проблема с шаблонами
Отправлено: Rotten_c от Сентябрь 03, 2012, 22:26
Igors
Теперь кажется понял. Sorter следовало объявлять
Код
C++ (Qt)
template <class T, class U, class S>
U* MemoryCellsManager::takeObject(
list< GameObjMemCell<T,U> > ObjGiver,
S Sorter,
int& initsize)
?

И в качестве Sorter передать наследника binary_function


Название: Re: Проблема с шаблонами
Отправлено: Igors от Сентябрь 03, 2012, 22:39
Можно, но так "еще больше магии". Может просто так
Код
C++ (Qt)
ObjGiver.sort(sortByFreeObjs_less <T, U>());
 


Название: Re: Проблема с шаблонами
Отправлено: Rotten_c от Сентябрь 03, 2012, 22:59
Почти так же и сделал. Ваш вариант мне нравится даже больше...