Search code examples
c++compiler-errorsiteratormember-functionsstdset

Why can't I call a non-const member function on an element in an std::set?


I hve the next code:

set<Item> temp_items;
set < Item >::iterator it;
temp_items = user->second.get_items();
for (it = temp_items.begin(); it != temp_items.end(); it++)
{
    if (counter == (choice - 1))
    {
        it->get_count();
    }
}

The item function i trying to call is:

int Item::get_count() { return _count; }

I don't have in here any const type that should prevent me from accessing the item object, and still, I get the next message:

the object has type qualifiers that are not compatible with the member function

object type is const

How can I fix it?


Solution

  • In short: you can only call const functions on set iterators.

    Explanation:

    The set is internally sorted by the Item. So when you access a reference (via iterator) you are not allowed to do something to change the value of the Item (this was actually easily possible in earlier c++ versions).

    What happens when you accidentally change the value this would not change the internal "ordering" accordingly and the lookup can fail even while the object is "there" in theory.

    Imagine this with numbers you have a set

    1 2 3 4 5 6 7 8 9
    

    Now you change the value of 9 to 0 (by reference)

    1 2 3 4 5 6 7 8 0
    

    Now when you would look for a 0 and the container has a smart lookup it would use a binary search and would assume 0 is on the far left. This would result in 0 not being found.

    (Note: this is just a simplified example. Not a definite explanation on how a set is implemented)

    That is why the reference to the key is a const reference and why you only can call const functions on those (same applies for keys on a map).