So I have written a custom iterator for std::map
that allows access to just the "values" of the map and I was wondering if it is the "correct" way to implement std::iterator
(acts identically to std::iterator
).
Here is the implementation I have written:
template<typename K, typename V>
class MapValueIterator : public std::iterator<std::forward_iterator_tag, V> {
public:
MapValueIterator();
MapValueIterator(typename std::map<K, V>::iterator iterator) : iterator(iterator) { }
MapValueIterator(const MapValueIterator<K, V> &iterator) : iterator(iterator.iterator) { }
MapValueIterator<K, V> &operator=(const MapValueIterator<K, V> &iterator) {
this->iterator = iterator.iterator;
}
bool operator==(const MapValueIterator<K, V> &iterator) const {
return this->iterator == iterator.iterator;
}
bool operator!=(const MapValueIterator<K, V> &iterator) const {
return this->iterator != iterator.iterator;
}
V &operator*() const {
return (iterator->second);
}
V *operator->() const {
return &(iterator->second);
}
MapValueIterator<K, V> &operator++() {
++iterator;
return *this;
}
MapValueIterator<K, V> operator++(int) {
return (*this)++;
}
private:
typename std::map<K, V>::iterator iterator;
};
And an example of how it can be used:
std::map<int, int> values;
values.insert(std::make_pair(0, 1));
values.insert(std::make_pair(1, 2));
values.insert(std::make_pair(2, 5));
MapValueIterator<int, int> begin(values.begin());
MapValueIterator<int, int> end(values.end());
for (auto iterator = begin; iterator != end; ++iterator) {
printf("%d\n", *iterator);
}
unordered_map
or amultimap
. You could arguably use a template-template parameter in this case. \$\endgroup\$unordered_map
andmap
have differing numbers of template parameters and all of the parameters are required when defining the template (i.e.template<template<class, class, class, class> class M, typename K, typename V>
only works formap
whiletemplate<template<class, class, class, class, class> class M, typename K, typename V>
only works forunordered_map
(note the extra class in the template). \$\endgroup\$template<template<class...> M, typename K, typename V>
which works perfectly! \$\endgroup\$M
. Then the constructor parameter isM::iterator
and the value type can be retrieved fromM::mapped_type
. \$\endgroup\$