views:

132

answers:

1

I'd like to use iterators from an STL list as keys in a map. For example:

using namespace std;

list<int> l;
map<list<int>::const_iterator, int> t;

int main(int argv, char * argc) {
l.push_back(1);
t[l.begin()] = 5;
}

However, list iterators do not have a comparison operator defined (in contrast to random access iterators), so compiling the above code results in an error:

/usr/include/c++/4.2.1/bits/stl_function.h:227: error: no match for ‘operator<’ in ‘__x < __y’

If the list is changed to a vector, a map of vector const_iterators compiles fine.

What is the correct way to define the operator < for list::const_iterator?

+3  A: 

Parameterise map with a custom comparator:

struct dereference_compare {
    template <class I>
    bool operator()(const I& a, const I& b) {
        return *a < *b;
    }
};
map<list<int>::const_iterator, int, dereference_compare> t;
Marcelo Cantos
GMan
Thanks for the tips, @GMan.
Marcelo Cantos
Thanks for the help! That did the trick.
Adrian
Note that the map will be unordered from the list point of view, that is, given two iterators `i1` and `i2`, with the former preceding the later, it is undefined whether `i1` is closer to the beginning of the list than `i2` (this would be different with a vector)
David Rodríguez - dribeas
@David, a vector would make no difference. The comparator compares by the iterator's target, not by the iterator itself. Worse, the map can hold iterators from different containers (though that isn't the intended use by the OP).
Marcelo Cantos