Форум программистов, компьютерный форум CyberForum.ru

Список - C++

Восстановить пароль Регистрация
 
 
Казаков Игорь
0 / 0 / 0
Регистрация: 01.03.2013
Сообщений: 34
21.07.2013, 10:54     Список #1
написал функцию, которая удаляет звено списка, если выполняется условие( если параметр функции == полю звена), однако вылетает ошибка list iterator not incrementable, когда удаляется последнее звено
C++
1
2
3
4
5
6
7
8
void CarPark::GoOutCarPark(int number)
{
    for (auto it = machine.begin(); it != machine.end(); it++)
    {
        if (number == it->GetNumber())
            it = machine.erase(it);
    }   
}
machine(список)
GetNumber- возвращает нужное поле
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.07.2013, 10:54     Список
Посмотрите здесь:

Список: связный список, в котором информация о книгах сортируется по убыванию стоимости. C++
C++ 3 класса: список, стек(как список), очередь(как список)
list. Cоздать список из результатов(с массивами), а потом просмотреть весь список C++
C++ создать список л3 из элементов входящих и в список л1 и в список л2
C++ Необходимо создать список, элемент которого может быть список
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 11:05     Список #2
Может не надо обновлять итератор?
C++
1
/*it = */machine.erase(it);
Добавлено через 5 минут
Хотя нет.. судя по всему это не исправит ошибку.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.07.2013, 11:16     Список #3
нужен не erase, а remove
http://cpp.com.ru/meyers/ch1.html#t23

Добавлено через 8 минут
кроме того, как вариант рассмотри возможность использования list::remove_if
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 11:19     Список #4
Стоп. Нет никакой проблемы. Все работает прекрасно, и должно так работать.
Чего-то ты нам не договариваешь.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.07.2013, 11:22     Список #5
Может так?
C++
1
2
3
4
5
6
7
8
9
void CarPark::GoOutCarPark(int number)
{
    for (auto it = machine.begin(); it != machine.end(); it++)
    {
        if (number == it->GetNumber())
            it = machine.erase(it);
            --it;
    }   
}
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.07.2013, 11:33     Список #6
Цитата Сообщение от alsav22 Посмотреть сообщение
Может так?
C++
1
2
3
4
5
6
7
8
9
void CarPark::GoOutCarPark(int number)
{
* * for (auto it = machine.begin(); it != machine.end(); it++)
* * {
* * * * if (number == it->GetNumber())
* * * * * * it = machine.erase(it);
* * * * * * --it;
* * } * 
}
Тогда уж так:
C++
1
2
3
4
5
6
7
8
9
10
11
void CarPark::GoOutCarPark(int number)
{
    auto it = machine.begin();
    while( it != machine.end())
    {
        if (number == it->GetNumber())
            machine.erase(it++);
        else 
            it++;
    }   
}
Добавлено через 2 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
--it;
а какой тип у it? разве итератор может быть одновременно инверсным и нет?

Не по теме:

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
нужен не erase, а remove
http://cpp.com.ru/meyers/ch1.html#t23
туплю... просто вспомнил совет мейерса... а он там немного по другому поводу.

castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 11:47     Список #7
Он может быть двунаправленным, каким он и является.
Только я все равно не пойму, почему вы все-таки настаиваете на том, что тут вообще имеет место ошибка?

Добавлено через 11 минут
Хотя, правильней все же будет так:
C++
1
2
3
4
5
6
        auto it = machine.begin();
        while ( it != machine.end() ) {
            if ( number == it->GetNumber() ) {
                it = machine.erase( it );
            } else ++it;
        }
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.07.2013, 11:55     Список #8
Цитата Сообщение от lazybiz Посмотреть сообщение
Он может быть двунаправленным, каким он и является.
по-моему, авто это какая то левая нестандартная возможность для итераторов.
Я знаю, что по стандарту авто это спецификатор класса памяти. И он практически не используется, т.к. локальные переменные и так хранятся как auto без явного на то указания. (книга K&R)
Впрочем можно наверное просто так написать
C
1
2
auto int i;
for (i=; i<10; i++){
Добавлено через 5 минут
C
1
2
auto int i;
for (i=0; i<10; i++){
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.07.2013, 11:58     Список #9
Цитата Сообщение от lazybiz Посмотреть сообщение
Только я все равно не пойму, почему вы все-таки настаиваете на том, что тут вообще имеет место ошибка?
Если erase возвращает итератор на следующий элемент, то далее, в цикле, он сразу инкременируется и получается, что следующий, после удалённого элемент, вообще пропускается.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 11:59     Список #10
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
по-моему авто это какая то левая нестандартная возможность для итераторов.
auto - попросту автоматический тип, определяемый на этапе компиляции.
Можно конечно же и так написать: list<int>::iterator it = machine.begin();
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.07.2013, 12:02     Список #11
При удалении последнего, erase() вернёт end, в цикле будет уже end + 1, выхода из цикла не будет.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 12:04     Список #12
alsav22, согласен, но на практике такого не происходит (по крайней мере у меня).
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.07.2013, 12:05     Список #13
Цитата Сообщение от lazybiz Посмотреть сообщение
auto - попросту автоматический тип, определяемый на этапе компиляции.
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
по стандарту авто это спецификатор класса памяти.
Таки спецификатор класса памяти это. Аналогично static, только наоборот.
C++
1
2
3
4
5
void foo(){
static int a;//спецификатор static
auto int b;//спецификатор auto
int c;//спецификатор auto по-умолчанию
}
Добавлено через 42 секунды
Цитата Сообщение от lazybiz Посмотреть сообщение
alsav22, согласен, но на практике такого не происходит (по крайней мере у меня).
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.07.2013, 12:06     Список #14
Цитата Сообщение от lazybiz Посмотреть сообщение
alsav22, согласен, но на практике такого не происходит (по крайней мере у меня).
Я не проверял, но как такое может быть?
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
21.07.2013, 12:06     Список #15
Ошибки, скорее всего, от того, что итераторы инвалидируются как попало.

Если уж вы не боитесь новых стандартов, то можно вот так сделать.
C++
1
2
3
4
5
6
7
8
9
void CarPark::GoOutCarPark(int number) {
  auto firstRemoved = std::remove_if(vector.begin(), vector.end(), 
    std::bind(
      std::equal_to<int>(),
      // тут не знаю типа данных, подставьте вместо Machine
      std::bind(&Machine::GetNumber, std::placeholders::_1),
      number));
  machine.erase(firstRemoved, machine.end());
}
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 12:06     Список #16
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Таки спецификатор класса памяти это.
А ты понимаешь что это значит?
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.07.2013, 12:12     Список #17
Цитата Сообщение от lazybiz Посмотреть сообщение
А ты понимаешь что это значит?
несомненно.
а) как минимум не сработает такое
C
1
2
auto i=0;//не работает
auto int j=0;//работает
Ну и этот спецификатор действительно редко используется, т.к. при объявлении локальных переменных эти записи всё равно эквивалентны.
C
1
2
3
4
void foo(){
int i;
auto int i;//можно и так объявить
}
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 12:13     Список #18
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
auto i=0;//не работает
Да неужели?
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.07.2013, 12:16     Список #19
Цитата Сообщение от lazybiz Посмотреть сообщение
А ты понимаешь что это значит?
а ты понимаешь, что значит "класс памяти"?
Есть два класса памяти: статический и автоматический. Автоматические объекты локальны и исчезают после выхода из блока.
Статические - нет.
Например, можно использовать статическую переменную для подсчёта количества вызовов фунуции.
C
1
2
3
4
5
6
7
void foo(){
static int cnt=0;
auto int tmp=0;//tmp всегда будет сбрасываться в 0
cnt++;
tmp++;
printf("cnt=%d tmp=%d", cnt, tmp);
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2013, 12:26     Список
Еще ссылки по теме:

Создать список, после каждого отрицательного числа вставить в список 0 C++
Сформировать список из 10 работников, используя динамическую структуру данных двусвязный список C++
C++ Сформировать список из 10 книг, используя динамическую структуру данных односвязный список

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
21.07.2013, 12:26     Список #20
Открою для тебя один секрет, начиная со стандарта С++11 auto не имеет семантику спецификатора класса памяти, а является просто ключевым словом.
Почитай на досуге: http://en.cppreference.com/w/cpp/language/auto

Добавлено через 3 минуты
Заодно обращаю твоё внимание на то, что судя по теме, ТС использует именно стандарт С++11.
Yandex
Объявления
21.07.2013, 12:26     Список
Ответ Создать тему
Опции темы

Текущее время: 08:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru