Why can't C++ set iterators be cast to bool?

boolean, c++, casting, set, stl

Solution

Iterators in the C++ standard library do not know about the container where they came from, and so they cannot in general know whether they've reached the end. This is deliberate, so as to allow iterators to be as light-weight as possible – you don't pay for what you don't use. (Iterators generalize the idea of pointers, and a pointer is an iterator.)

You can always build your own self-aware iterator as a pair of native iterators.

In fact, some people have argued that such a pair, or range is the more natural way to talk about collections, and there are libraries, as well as library adapters, to implement ranges (e.g. Boost.Range).

Update: Iterators are more low-level than ranges, and it is debatable which concept is a better solution (though one would need to define the problem first). Iterators are a bit more flexible; for example, if you mutate a container while iterating over it, you'd have to "update" all range-pairs to receive the new "end" value. (Or otherwise switch to a completely "range-centered" algorithmic style.) Alternatively you could store a reference to the container in the iterator and recompute `end()` each time it's needed. Already you can see how there are lots of non-trivial details, and the C++ standard library simply decided not to make those choices for you but instead only give you the building blocks to write the solution that fits your own problem best.

Problem

For an STL set (s), it seems like you should be able to say: ``` if(s.find(x)) { //Something } ``` as opposed to ``` if(s.find(x) != s.end()) { //Something } ``` Furthermore, if set-iterators could be cast to bool (true if the internal pointer is not null), you would be able to. Why don't STL set iterators have this simple functionality? Was this intentionally left out? CLARIFICATION: Alternatively, set's could just have a set::contains(x) method which returns a bool directly, but this doesn't seem to be implemented either. I know it's only a couple characters, but in the case where s is a return value from some function, this can be frustrating because of the need to create a temporary variable, ie (supposing m is of type `map<int,set<int>>`) ``` const set<int>& s = m[i]; return s.find(x) != s.end(); ``` as opposed to ``` return m[i].contains(x); ``` or ``` return m[i].find(x); ``` EDIT: I didn't realize the count() method could be used as contains(). Voted to close since this question doesn't properly phrase what I really should have asked: Do STL::set's have a "contains" method?

Original source