HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Custom C++ iterator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
customiteratorstackoverflow

Problem

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
class MapValueIterator : public std::iterator {
public:
MapValueIterator();

MapValueIterator(typename std::map::iterator iterator) : iterator(iterator) { }

MapValueIterator(const MapValueIterator &iterator) : iterator(iterator.iterator) { }

MapValueIterator &operator=(const MapValueIterator &iterator) {
this->iterator = iterator.iterator;
}

bool operator==(const MapValueIterator &iterator) const {
return this->iterator == iterator.iterator;
}

bool operator!=(const MapValueIterator &iterator) const {
return this->iterator != iterator.iterator;
}

V &operator*() const {
return (iterator->second);
}

V *operator->() const {
return &(iterator->second);
}

MapValueIterator &operator++() {
++iterator;

return *this;
}

MapValueIterator operator++(int) {
return (*this)++;
}

private:
typename std::map::iterator iterator;
};


And an example of how it can be used:

std::map values;

values.insert(std::make_pair(0, 1));
values.insert(std::make_pair(1, 2));
values.insert(std::make_pair(2, 5));

MapValueIterator begin(values.begin());
MapValueIterator end(values.end());

for (auto iterator = begin; iterator != end; ++iterator) {
printf("%d\n", *iterator);
}

Solution

It looks about perfect.

You got the post increment wrong though:

MapValueIterator operator++(int) {
    return (*this)++;
}


I believe this goes into an infinite recursion.

Thus this is normally implemented as:

MapValueIterator operator++(int) {
    MapValueIterator  result(*this);  // get a copy for return
                                            // so this can be used
                                            // unaltered in the expression

    // Now implement the current object.
    ++(*this);

    // Returned the saved copy.
    return result;
}


The only difference is that the std::map::iterator type actually implements the Bidirectional iterator concept. The question is why is your iterator only implement the Forward iterator concept.

Code Snippets

MapValueIterator<K, V> operator++(int) {
    return (*this)++;
}
MapValueIterator<K, V> operator++(int) {
    MapValueIterator<K, V>  result(*this);  // get a copy for return
                                            // so this can be used
                                            // unaltered in the expression

    // Now implement the current object.
    ++(*this);

    // Returned the saved copy.
    return result;
}

Context

StackExchange Code Review Q#122111, answer score: 8

Revisions (0)

No revisions yet.