The C++ STL does not seem to use purely abstract base classes (aka interfaces) very often. I know that most things can be achieved with the STL algorithms or clever template metaprogramming.
But still, for some use cases (for example, in an API, if I do not want to be specific about the type of container I get, just about the elements it contains), an interface of the following form would be nice:
template<typename T> struct forward_iterable {
struct iterator {
typedef T value_type;
typedef T& reference;
typedef T* pointer;
virtual reference operator*() const = 0;
virtual pointer operator->() const = 0;
virtual bool operator==(const iterator&) const = 0;
virtual bool operator!=(const iterator&) const = 0;
virtual operator const_iterator() const = 0;
virtual iterator& operator++() = 0;
virtual iterator operator++(int) = 0;
};
struct const_iterator { ... }; // similar, but with const references
virtual iterator begin() = 0;
virtual const_iterator begin() const = 0;
virtual iterator end() = 0;
virtual const_iterator end() const = 0;
};
If the STL containers implement this class as non-virtual function, this would, in my opinion, not affect performance (if I use the containers directly and not via this interface). So why are there so few “interfaces” in the STL? Or am I just thinking too much in “Java” terms?
STL (which is a subset of the standard library) does not use OOP (as in runtime polymorphism) at all and that’s by design.
With your design, wouldn’t there be problems returning iterators by value (covariance doesn’t work for value types)? That is, wouldn’t inevitably the whole thing either have to rely on static members (that you can return by reference) or on heap-allocated iterators? The latter would seem rather awkward in a non-garbage-collected language.
What you are describing (an iterator templated on value type) can be achieved using a technique called type-erasure (and you can find
any_iteratorimplementations out there) just like boost’sfunctionandanytypes.The basic idea is:
It may be more complicated than that (e.g need to do something about describing and enforcing iterator category?, how would comparing two any_iterators work (double dispatch/RTTI?)).