Помощь с функцией стирания списка C ++ - PullRequest
0 голосов
/ 17 декабря 2008

Я пытаюсь сделать простое стирание и постоянно получаю ошибки.

Вот фрагмент кода для моего стирания:

std::list<Mine*>::iterator iterMines = mines.begin();
for(int i = oldSizeOfMines; i >0 ; i--, iterMines++)
{
    if(player->distanceFrom(*iterMines) < radiusOfOnScreen)
    {
        onScreen.push_back(*iterMines);
        iterMines = onScreen.erase(iterMines);
        iterMines--;
    }
}

Я получаю сообщение компилятора:

1>c:\users\owner\desktop\bosconian\code\bosconian\environment.cpp(158) : error C2664: 'std::list<_Ty>::_Iterator<_Secure_validation> std::list<_Ty>::erase(std::list<_Ty>::_Iterator<_Secure_validation>)' : cannot convert parameter 1 from 'std::list<_Ty>::_Iterator<_Secure_validation>' to 'std::list<_Ty>::_Iterator<_Secure_validation>'
1>        with
1>        [
1>            _Ty=SpaceObject *,
1>            _Secure_validation=true
1>        ]
1>        and
1>        [
1>            _Ty=Mine *,
1>            _Secure_validation=true
1>        ]
1>        and
1>        [
1>            _Ty=SpaceObject *,
1>            _Secure_validation=true
1>        ]
1>        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Я озадачен, потому что я верю, что даю правильный итератор.

Mine является подклассом SpaceObject (подкласс второго поколения)

Это как-то связано с этим? И как бы это исправить?

Ответы [ 3 ]

4 голосов
/ 17 декабря 2008

Проблема в том, что вы пытаетесь использовать итератор шахт в качестве итератора в списке на экране. Это не будет работать.

Вы хотели вызвать mines.erase (iterMines) вместо onScreen.erase (iterMines)?

2 голосов
/ 17 декабря 2008
std::list<Mine*>::iterator iterMines = mines.begin();
for(int i = oldSizeOfMines; i >0 ; i--, iterMines++)
{
        if(player->distanceFrom(*iterMines) < radiusOfOnScreen)
        {
                onScreen.push_back(*iterMines);
                iterMines = onScreen.erase(iterMines);
                iterMines--;
        }
}

Одна реальная проблема и одно возможное решение:

erase даст вам следующий итератор после удаленного элемента. Так что, если вы находитесь в начале и удалите, вам будет дано новое начало. Если вы затем уменьшите итератор, вы уменьшите его перед началом. И это неверно. Лучше вывести iterMines++ в тело цикла:

std::list<Mine*>::iterator iterMines = mines.begin();
for(int i = oldSizeOfMines; i >0 ; i--)
{
        if(player->distanceFrom(*iterMines) < radiusOfOnScreen)
        {
                onScreen.push_back(*iterMines);
                iterMines = mines.erase(iterMines); // change to mines!!
        } else { 
            ++iterMines; // better to use ++it instead of it++
        }
}

Лучше использовать предварительное увеличение для этого, поскольку вы никогда не знаете, что делает итератор за кулисами, когда он создает свою копию. ++it вернет новый итератор, а it++ вернет копию итератора перед приращением. Я прокомментировал ту часть, где возможное решение тоже:)

0 голосов
/ 08 января 2009

более простой метод List.erase (р) 的 用法

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...