0

I have a vector of Persons. At the time i thought it would be a good idea to give every person a unique id. And so i did:

class Person {
    Person::Person(): id(currentID++){
    }
    const int id;
}

After a while i wanted to build a vector of persons and so i learned that i'd have to provide a few more functions:

An element of vector must be:

Copyable, i.e. have a constructor compatible with T(const T&)
Assignable, i.e. have an operator= compatible with operator=(const T&).
Default-constructible, i.e. have a constructor compatible with T().

And so i did my best and came up with

Person::Person(const Person& other): id(other.id) {
}
Person& Person::operator=(const Person& other) 
}

Everything seemed to be working splendidly.

But one day i tried to erase an element from my vector just like i learned

vector<Person> persons;
persons.push_back(Person()); //id 0
persons.push_back(Person()); //id 1
persons.push_back(Person()); //id 2

vector<Person>::iterator it;
for(it = persons.begin() ; it != persons.end() ; ) {
    if(it->getID() == 1) {
        it = persons.erase(it);
    } else {
        it++;
    }
}
//persons.size() == 1

I checked the debugger and saw that erase uses the operator= to move the elements after the call to erase. Obviously id wasn't changed and so i deleted every element after id 1 in my vector.

Why is that the case? I always thought vector erase just would move the pointer from element 0 to 2 to drop element 1.

How should i deal with my const id? Should i include it in operator=?

I read about a move operator in C+11 (which i use), would vector use this special operator if i provide it?

Community
  • 1
  • 1
Sebastian Schmitz
  • 1,884
  • 3
  • 21
  • 41
  • It would be great if you could post valid code. The semantics of your assignment operator make no sense, the two objects are still different after the assignment. It looks like you have accessor functions for `id`, so what's the point of making it `const`? Drop the `const`, and if your class really is this trivial, get rid of the copy constructor & assignment operator. Let the compiler generate those for you. Your problem should go away. Also, search for *erase-remove idiom* for another way of removing items from a `vector`. – Praetorian Jun 03 '14 at 13:58
  • possible duplicate of [Vector of structs with const members?](http://stackoverflow.com/questions/8467968/vector-of-structs-with-const-members) – Danvil Jun 03 '14 at 13:58
  • @Danvil A little reluctant to close it as duplicate of that because the OP got around the *Assignable* requirement by writing a (broken) copy assignment operator. But he is essentially facing the same problem as the other question. – Praetorian Jun 03 '14 at 14:03
  • From the other thread: "Write your own copy-assignment operator, and think of a way to deal with "copying" a const member." That pretty much sums up what i did. But as @Praetorian pointed out it's broken. My question is what i should do? Another data structure? – Sebastian Schmitz Jun 03 '14 at 14:07
  • `class Person` is a strongly reduced versions of my real class. I tried to do a minimum working example. – Sebastian Schmitz Jun 03 '14 at 14:07
  • 1
    Just don't use a `const` data member. – juanchopanza Jun 03 '14 at 14:10
  • @juanchopanza How should i (try to) ensure that id is not manipulated? – Sebastian Schmitz Jun 03 '14 at 14:15
  • 1
    Don't provide any public or protected access to it. – juanchopanza Jun 03 '14 at 14:16
  • @SebastianSchmitz Also, don't write code that manipulates it. – molbdnilo Jun 03 '14 at 14:18

0 Answers0