Удаление указателя из вектора с использованием циклов (не итераторов) - PullRequest
0 голосов
/ 30 декабря 2018

У меня есть метод, который передает объект, находит этот объект в векторе указателей, сопоставляя его адрес в цикле, и должен удалить соответствующий элемент из вектора, не удаляя элемент (т.е. элемент должен все ещесуществуют в памяти).В настоящее время это метод:

void remove(Soldier& soldier) {
    for (size_t i = 0; i < armySize(); ++i) {
        if (army[i] == &soldier) {
            cout << army[i]->getName() << "is removed" << endl;
            army.erase(i);
            break;
        }
    }
}

Где soldier - объект, который необходимо удалить, а army - вектор Soldier указателей.Оператор if работает, это означает, что адрес soldier и элемент в векторе совпадают.Проблема в том, что я получаю сообщение об ошибке «Нет соответствующей функции-члена для вызова« стирания »».Как бы я это исправить, не используя итераторы (без нового, удалить или начать метод)?

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Если вы посмотрите на объявление std::vector::erase, оно будет:

iterator erase( const_iterator pos );

Как видите, аргумент является целым числом.Вы пытаетесь передать целое число в качестве аргумента.Таким образом, разрешение перегрузки не находит перегрузки с типом передаваемого аргумента.Вот что означает ошибка «нет соответствующей функции-члена для вызова« стирания »* .

Невозможно использовать std::vector::erase без использования итератора.


Как бы это исправить, не используя итераторы

Вы можете перезаписать удаляемый элемент последним элементом, а затем вызвать pop_back, чтобы удалить дубликат.И то, и другое можно сделать без итераторов.

Если вы хотите сохранить порядок, как erase, перезапишите целевой элемент следующим.Затем переписать следующий с последующим, и так до конца вектора.Тогда pop_back.Тем не менее, я бы порекомендовал использовать итераторы и erase вместо этого.Нет необходимости усложнять программу, произвольно запрещая использование итераторов.

0 голосов
/ 30 декабря 2018

Вы можете поменять элемент, который пытаетесь стереть, на последний и использовать std::vector::pop_back():

 if( i != army.size() - 1 ) 
     std::swap( army[i], army.back() );
 army.pop_back();

, если вы используете указатели, вы можете просто переопределить:

army[i] = army.back();
army.pop_back();

Этот метод будет более эффективным, чем вызов std::vector::erase(), но это повлияет на порядок элементов.

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