Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

stl

stdset

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 ?

like image 806
Jabberwocky Avatar asked Mar 01 '17 13:03

Jabberwocky


People also ask

How do you check if a set contains an element in C++?

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.

How do you find something in a set in C++?

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().

How do you find an element in a set?

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.

Is std :: set ordered?

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).


2 Answers

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.

like image 130
Martin Bonner supports Monica Avatar answered Sep 28 '22 02:09

Martin Bonner supports Monica


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.

like image 35
Lmn Avatar answered Sep 28 '22 00:09

Lmn