lolololol ol
lolololol ol

Reputation: 868

C++ std::map::iterator found nothing, yet subscript operator returns reference to mapped value?

Probably doing something very dumb, but I can't figure out why find doesn't find an element with a key equivalent to suppID.

Yet when I pass the subscript operator suppID, it returns what a reference to its mapped value (implying it found something, right?).

typedef std::map<SuppID, Supplement *> Supplement_t;

Supplement_t::iterator it = supplements.find(suppID);  //it = supplements.end()

cout << "Supplement name: " << supplements[suppID]->getName() << endl; // "Cytogainer"
... // Returns few of many other data members I tested...

Upvotes: 0

Views: 86

Answers (2)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275976

When writing < for an associative container it is easy to get it wrong.

The easy way is to write a function or method that returns a tuple, either of references or values or a mixture. Call if foo.

friend bool operator<( self const& lhs, self const& rhs ){
  return lhs.foo()<rhs.foo();
}

If you write a < wrong, you will get simply insane behaviour.

Upvotes: 1

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

That's because std::map inserts a default value for new key values that do not exist yet when using the subscript operator.

As stated here:

1) Inserts value_type(key, T()) if the key does not exist. This function is equivalent to return insert(std::make_pair(key, T())).first->second; -key_type must meet the requirements of CopyConstructible. -mapped_type must meet the requirements of CopyConstructible and DefaultConstructible. If an insertion is performed, the mapped value is value-initialized (default-constructed for class types, zero-initialized otherwise) and a reference to it is returned.

Upvotes: 2

Related Questions