Доброго всем времени суток!
такой код:
....
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 не компилировалось!)
Помогите чем можете!
С уважением, Павел.
Добавлена раскраска — Кодт
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Здравствуйте, Pavel515, Вы писали:
P>Помогите чем можете!
По стандарту erase(iterator) для ассоциативных контейнеров возвращает void.
STL идущий с VC возвращает итератор в качествен расширения.
Пиши так:
if (...)
Keys.erase(k++);
Здравствуйте, Андрей Коростелев, Вы писали:
АК>Здравствуйте, 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++;
}
Нет! ?
неужели все как-то держится на "гонке сигналов" ???
С уважением, Павел.
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Здравствуйте, 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>неужели все как-то держится на "гонке сигналов" ???
Конечно нет.
Здравствуйте, Bell, Вы писали:
Я все понял: все по приоритетам
1 создается копия k
2 делается инкримент k
3 вызывается функция
в результате правильный итератор в k и правильный удаляется
Учу мат-часть!!!
Спасибо Bell!
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)