Why does std::set not have a "contains" member function?

I'm heavily using std::set<int> and often I simply need to check if such a set contains a number or not.

I'd find it natural to write:

if (myset.contains(number))
   ...

But because of the lack of a contains member, I need to write the cumbersome:

if (myset.find(number) != myset.end())
  ..

or the not as obvious:

if (myset.count(element) > 0) 
  ..

Is there a reason for this design decision ?


I think it was probably because they were trying to make std::set and std::multiset as similar as possible. (And obviously count has a perfectly sensible meaning for std::multiset.)

Personally I think this was a mistake.

It doesn't look quite so bad if you pretend that count is just a misspelling of contains and write the test as:

if (myset.count(element)) 
   ...

It's still a shame though.


To be able to write if (s.contains()), contains() has to return a bool (or a type convertible to bool, which is another story), like binary_search does.

The fundamental reason behind the design decision not to do it this way is that contains() which returns a bool would lose valuable information about where the element is in the collection. find() preserves and returns that information in the form of an iterator, therefore is a better choice for a generic library like STL. This has always been the guiding principle for Alex Stepanov, as he has often explained (for example, here).

As to the count() approach in general, although it's often an okay workaround, the problem with it is that it does more work than a contains() would have to do.

That is not to say that a bool contains() isn't a very nice-to-have or even necessary. A while ago we had a long discussion about this very same issue in the ISO C++ Standard - Future Proposals group.