И снова STL на разных платформах
От: Pavel515  
Дата: 08.09.06 13:44
Оценка:
Доброго всем времени суток!

такой код:
....

typedef unsigned char* key_t;

#include <map>

using namespace std;

struct key_t_less : binary_function<key_t, key_t, bool> {
    bool operator()(const key_t& a, const key_t& b) const {
        return memcmp(a,b,a[0]-5)<0;}};
typedef multiset<key_t,key_t_less> keys_t;


....

void Check(keys_t& Keys)
{
...
keys_t::iterator k;
...
k=Keys.begin();
while(k!=Keys.end())
{
...
if(..)k=Keys.erase(k);
else k++;
}

...

на windows прокатывает все! и работает правильно!
а на Solaris 9 g++ 3.3.2

выдает ошибку при компиляции :
core_cmd.cpp: In function `void Check(keys_t&)':
core_cmd.cpp:256: error: no match for 'operator=' in 'k =
   (+Keys)->std::multiset<_Key, _Compare, _Alloc>::erase(typename
   std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare,
   _Alloc>::const_iterator) [with _Key = unsigned char*, _Compare =
   key_t_less, _Alloc = std::allocator<unsigned char*>](k)'
/usr/local/include/c++/3.3.2/bits/stl_tree.h:184: error: candidates are:
   std::_Rb_tree_iterator<unsigned char*, unsigned char* const&, unsigned char*
   const*>& std::_Rb_tree_iterator<unsigned char*, unsigned char* const&,
   unsigned char* const*>::operator=(const std::_Rb_tree_iterator<unsigned
   char*, unsigned char* const&, unsigned char* const*>&)

голову уже сломал!
(у меня такое раньше было: проблема оказалась в предикате сравнения, но тогда ни на windows, ни на Solaris не компилировалось!)

Помогите чем можете!

С уважением, Павел.
Добавлена раскраска — Кодт
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Re: И снова STL на разных платформах
От: Андрей Коростелев Голландия http://www.korostelev.net/
Дата: 08.09.06 21:24
Оценка: 1 (1)
Здравствуйте, Pavel515, Вы писали:

P>Помогите чем можете!


По стандарту erase(iterator) для ассоциативных контейнеров возвращает void.
STL идущий с VC возвращает итератор в качествен расширения.

Пиши так:
if (...)
  Keys.erase(k++);
-- Андрей
Re[2]: И снова STL на разных платформах
От: Pavel515  
Дата: 11.09.06 05:39
Оценка:
Здравствуйте, Андрей Коростелев, Вы писали:

АК>Здравствуйте, Pavel515, Вы писали:


P>>Помогите чем можете!


АК>По стандарту erase(iterator) для ассоциативных контейнеров возвращает void.

АК>STL идущий с VC возвращает итератор в качествен расширения.

АК>Пиши так:

АК>
АК>if (...)
АК>  Keys.erase(k++); 
АК>




Спасибо Андрей! вроде бы заработало, но тогда встречный вопрос:

почему тогда конструкция типа

for(k=Keys.begin();k!=Keys.end();k++)
{
...





if(...)
{
Keys.erase(k);
continue;
}



}
дает исключение при первом удалении, а


k=Keys.begin();
while(k!=Keys.end())
{
...
if(...)
{
Keys.erase(k++);
continue;
}
k++;
}

Нет! ?

неужели все как-то держится на "гонке сигналов" ???

С уважением, Павел.
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Re[3]: И снова STL на разных платформах
От: Bell Россия  
Дата: 11.09.06 06:48
Оценка:
Здравствуйте, Pavel515, Вы писали:

P>почему тогда конструкция типа

P>for(k=Keys.begin();k!=Keys.end();k++)
P>{
P>...
P>   if(...)
P>   {
P>      Keys.erase(k);
P>      continue;
P>   }
P>}

P>дает исключение при первом удалении, а

После инструкции Keys.erase(k); итератор k становится недействительным, и в конце тела цикла for инкремент выполняется на этом недействительном итераторе.

P>..., а

P>k=Keys.begin();
P>while(k!=Keys.end())
P>{
P>...
P>if(...)
P>{
P>Keys.erase(k++);
P>continue;
P>}
P>k++;
P>}


P>Нет! ?


Keys.erase(k++); в данном случае все в порядке, т.к. используется постфиксная форма operator ++, и в erase уходит копия значения итератора, а у нас остается валидный инкрементированный итератор.

P>неужели все как-то держится на "гонке сигналов" ???

Конечно нет.
Любите книгу — источник знаний (с) М.Горький
Re[4]: И снова STL на разных платформах
От: Pavel515  
Дата: 11.09.06 06:53
Оценка: :)
Здравствуйте, Bell, Вы писали:

Я все понял: все по приоритетам
1 создается копия k
2 делается инкримент k
3 вызывается функция

в результате правильный итератор в k и правильный удаляется

Учу мат-часть!!!

Спасибо Bell!
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.