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 ?
The standard solution to check for existence of an element in the set container ( std::set or std::unordered_set ) is to use its member function find() . If the specified element is found, an iterator to the element is returned; otherwise, an iterator to the end of the container is returned.
C++ set find() C++ set find() function is used to find an element with the given value val. If it finds the element then it returns an iterator pointing to the element otherwise, it returns an iterator pointing to the end of the set i.e. set::end().
set find() function in C++ STL Parameters: The function accepts one mandatory parameter element which specifies the element to be searched in the set container. Return Value: The function returns an iterator which points to the element which is searched in the set container.
Yes, std::set stores its elements in such a way that iterating over the elements will be done in sorted order (and the call to std::adjacent_find is to show that std::set stores unique items as well).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With