1

vector erase function brings up an error whereas clear function works. What is the reason for this..?

#include <algorithm>
#include <vector>
#include <iostream>
struct person_id{
    person_id() = default;
    person_id(int id) : p_id (id) {}

    bool operator==(const person_id& other) { return p_id == other.p_id; }
    int p_id;
};
using std::cout;
using std::endl;

int main(int argc, char* argv[]) {
    std::vector<person_id> people;

    person_id tmp_person;
    tmp_person.p_id = 5;
    people.push_back(tmp_person);

    people.erase(5); // error : “No matching function for call 'erase'
    people.clear(); // works

    return 0;
}
유 길재
  • 55
  • 1
  • 4
  • 2
    Please, try `people.erase(people.begin() + 0);` instead. You cannot provide a key in a `std::vector::erase` (like e.g. in a `std::set`). Only, iterators are accepted. – Scheff's Cat Jan 16 '20 at 08:01
  • 1
    [`std::vector::erase`](https://en.cppreference.com/w/cpp/container/vector/erase) – WhozCraig Jan 16 '20 at 08:02

3 Answers3

5

std::vector::erase() takes as argument the iterator. So if you want to delete the 6th element you need to do in this way: people.erase(people.begin() + 5);. If you want to delete the 1st element just use people.erase(people.begin());

Reference: http://www.cplusplus.com/reference/vector/vector/erase/

Edit: Erase element which will meet the conditions:

The 1st way: Create temp person_id with needed id, and find it in the vector:

person_id personToCheck(5);
auto iter = std::find(people.begin(), people.end(), personToCheck);
if(iter != people.end())
{
   people.erase(iter);
}

The 2nd way: Create new operator== in the person_id class: bool operator==(const int ID) { return p_id == ID; }

auto iter = std::find(people.begin(), people.end(), 5); //the 5 is the ID
if(iter != people.end())
{
   people.erase(iter);
}

The 3rd way: Create lambda and use it to find the element in the vector

auto iter = std::find_if(people.begin(), people.end(), [](const person_id &p) { return p.p_id == 5; });
if(iter != people.end())
{
   people.erase(iter);
}
Raffallo
  • 651
  • 8
  • 19
3

This is the <vector> erase function prototype:

iterator erase (iterator position);

You can't call it with an int parameter. You need a vector::iterator.

acraig5075
  • 10,588
  • 3
  • 31
  • 50
SuperG280
  • 271
  • 3
  • 9
2

vector::erase doesn't know that by number 5 you mean the person with ID=5. You need to tell it so by providing an iterator to that item.

First find the item you want to erase by searching for that condition.

auto itr = std::find_if(people.begin(), people.end(), [](const person_id &p) { return p.p_id == 5; });

Then, if the search was successful, you can erase the iterator that was returned.

if (itr != people.end())
    people.erase(itr);
acraig5075
  • 10,588
  • 3
  • 31
  • 50