I looked at STL's forward iterator. I don't see any virtual functions anywhere. If I开发者_如何学C have a library that wants a forward iterator of strings how can I allow the function to take any forward iterator that returns strings? Is there anything in the standard library I can use?
There are no virtual methods as they are not meant to be used polymorphically (in the common sense of runtime polymorphism) but rather through templates (static polymorphism). The common approach is having the function that takes the iterators templatized on the type of the iterator. You can find many examples in the STL algorithm header:
template <class InputIterator, class Distance>
inline void distance(InputIterator first, InputIterator last, Distance& n);
In your particular case:
template <class ForwardIterator> // or InputIterator or whatever your needs are
void acceptIterators( ForwardIterator start, ForwardIterator end );
The additional restriction that it has to refer to strings can be implemented in term of type traits and enable_if:
template <class ForwardIterator>
std::enable_if< std::is_same< std::string,
typename iterator_traits<ForwardIterator>::value_type > >
void acceptIterators( ForwardIterator start, ForwardIterator end );
Using typetraits from c++0x, but the enable_if
and is_same
are available in boost if you need them in a compiler that does not have support for them.
If you need to be able to switch the types of iterators at runtime, you might want to look into any_iterator
that performs type erasure on the specific iterators providing a runtime polymorphic interface. It is described in the article On the Tension Between Object-Oriented and Generic Programming in C++, the implementation can be found in Adobe STLab.
You can write your own iterator and use it as:
std::for_each( make_myiterator(c.begin), make_myiterator(c.end), do_some() );
You can inherit from std::iterator
, or check Boost Iterator Facade — it will help you to write own iterator.
The usual way is to make functions that use iterator function-templates. It's what the standard library does.
If you want to accept any iterator over e.g. strings you need to use templates. There's no top-level iterator class that all other iterators inherit.
Writing conformant C++ iterators can be a pain, but Boost.Iterators helps you a great deal if your not afraid of templates. There's an example on how to use iterator_facade to create a simple iterator that you should have a look at. Boost.Iterators is a header only library so there's no need to link anything with your application/library.
精彩评论