Здравствуйте Kubyshev Andrey, Вы писали:
KA>Privet, KA>Kak mne sdelat' sortirovku std::list ispolzuya moyu sobstvennuyu func. sravneniya. Iskal , iskal v inete, no ponyal chto zadacha ne sovsem easy. Interesuet reshenie kak dlya vc++ tak i g++
определи (переопредели) для данных, которые ты хранишь в листе операцию "меньше" и алгоритм sort будет сортировать твой лист. Если непонятно, то приведи конкретный пример, на примере проще объяснить.
Здравствуйте Кодт, Вы писали:
К>Здравствуйте DarkGray, Вы писали:
DG>>Так в том то и дело, что это не работает. Так как вызывается operator() от класса greater, а не от твоего класса.
К>Расследовал. Действительно К>STL от VC++ хочется иметь предикат типа greater<T>, и он имеет именно его.
К>Похоже, халявы нет, и придется юзать контейнеры с произвольным доступом...
Здравствуйте Burkutsky, Вы писали:
B>Здравствуйте Кодт, Вы писали:
К>>Здравствуйте DarkGray, Вы писали:
К>>Похоже, халявы нет, и придется юзать контейнеры с произвольным доступом...
B>Зачем с произвольным доступом
Затем, что для контейнеров с произвольным доступом существуют алгоритмы сортировки по произвольному предикату сравнения. Тот же qsort.
B>смотрим определение
B>
B>просто либо делаем производный класс от нашего с переопределённым опретором >, ( если не встроенный тип ) B>либо класс оболочку с нужным оператором.
Ля-ля-ля! Солнышко, птички...
Хорошо, если для сортируемого типа не был определен оператор >: определяем и получаем удовольствие.
Если же был — то
template<.....> struct greater :.....
{
bool operator()(.....) {......}
};
struct MySuperPuperClass : public greater<.....>
{
bool operator()(.....) {......}
};
// так объявлен метод спискаvoid std::list<T>::sort(greater<T>& pred);
// вызываем
MySuperPuperClass sorter;
mylist.sort(sorter);
// компилятор первым делом приводит (greater<T>)(sorter)
// а у greater оператор-то не виртуальный!
Опаньки.
Если не верите — напишите и расставьте брекпоинты.
Здравствуйте Кодт, Вы писали:
К>// так объявлен метод списка К>void std::list<T>::sort(greater<T>& pred);
Еще хуже: void std::list<T>::sort(greater<T> pred); (без ссылки), так что, даже если бы (не дай бог) функция greater<T>::operator() была виртуальным, объект все равно срезался бы, и в любом случае была бы вызвана операция greater<T>::operator().
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Vsem privet,
Vot nashel chto po etomu povodu sovetuet Igor Tandetnik, navernyaka te kto chitaet inostrannye news groups po win programmingu ne raz videli eto name.
-----
Here's the deal. list::sort without the parameter sorts using less<T>
(in other words, <) in the ascending order, smallest at the head,
largest at the tail. list::sort with the parameter is supposed to accept
any predicate and sorts in such a way that, had the predicate been
less<T>, the sorted order would be the same as with parameterless
version. In other words, if Pr(A, B) == true, A will precede B in the
sorted order.
Now, the Dinkumware STL implementation shipped with MSVC6 does not
provide a templated version of list::sort, because of inferior compiler
template support at the time the implementation was frozen. Instead, the
predicate parameter is hardcoded to be greater<T>. This way, you can
sort in ascending order (with parameterless version) or descending order
(with hardcoded parameter), but not in any other order. This "feature"
made it into MSDN documentation, hence the confusion.
Now that the compiler is better, P.J. Plauger, one of the authors of
Dinkumware STL, recommends editing <list> header. Find a line
void sort(_Pr3 _Pr)
and put "template <class _Pr3>" in front of it, so it looks like
template <class _Pr3> // added line
void sort(_Pr3 _Pr)
You need to change both, since sort uses merge internally. This makes
std::list C++ standard-compliant. While you are at it, consider applying
the fixes from
Здравствуйте Кодт, Вы писали:
К>Здравствуйте Burkutsky, Вы писали:
B>>Здравствуйте Кодт, Вы писали:
К>>>Здравствуйте DarkGray, Вы писали:
К>>>Похоже, халявы нет, и придется юзать контейнеры с произвольным доступом...
B>>Зачем с произвольным доступом :???:
К>Затем, что для контейнеров с произвольным доступом существуют алгоритмы сортировки по произвольному предикату сравнения. Тот же qsort.
Ясен пень сушествуют, но насколь я понял из дисскусии надо именно для листа( или другого с последов. доступом )
B>>смотрим определение
B>>
B>>просто либо делаем производный класс от нашего с переопределённым опретором >, ( если не встроенный тип ) B>>либо класс оболочку с нужным оператором.
К>Ля-ля-ля! Солнышко, птички...
К>Хорошо, если для сортируемого типа не был определен оператор >: определяем и получаем удовольствие. К>Если же был — то К>
К>template<.....> struct greater :.....
К>{
К>bool operator()(.....) {......}
К>};
К>struct MySuperPuperClass : public greater<.....>
К>{
К>bool operator()(.....) {......}
К>};
К>// так объявлен метод списка
К>void std::list<T>::sort(greater<T>& pred);
К>// вызываем
К>MySuperPuperClass sorter;
К>mylist.sort(sorter);
К>// компилятор первым делом приводит (greater<T>)(sorter)
К>// а у greater оператор-то не виртуальный!
К>
К>Опаньки.
К>Если не верите — напишите и расставьте брекпоинты.
По ходу ты не понял идею, может я не понятно объяснил: не производный от структуры greater<.....>
а производный от _сортируемого типа_ с перегруженым оператором ( bool operator < ( const CMyUpType& _crVal ) const ) а не operator()(...).
то есть мы вообще _не трогаем_ greater.
в нём ( см. определение ) вызывается operator < уже _нашего_ типа который вернёт то, что мы хотим.
Вот что имелось ввиду:
template <class T>
class CMyUpTempl
{
T m_tContent; // не производный класс а оболочка для возможности использования встроенных типовpublic:
CMyUpTempl( const T& _crVal ):
m_tContent( _crVal )
{
}
inline operator T&()
{
return m_tContent;
}
inline operator T() const
{
return m_tContent;
}
inline bool operator > ( const CMyUpTempl& _crVal ) const// именно этот оператор вызовется в greater
{
return m_tContent < _crVal.m_tContent;
// return _WhatYouWantButDontForgetLogicCorrecpondingBetweenLogicOperators;
}
};
После чего
list< CMyUpTempl< int > > g_myList;
...
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_myList.push_back( 5 );
g_myList.push_back( 6 );
g_myList.push_back( 7 );
g_myList.sort( std::greater<CMyUpTempl< int> >());
int nVal1 = g_myList.front();
g_myList.pop_front();
int nVal2 = g_myList.front();
g_myList.pop_front();
int nVal3 = g_myList.front();
g_myList.pop_front();
return 0;
}