简体   繁体   中英

Iterating over sets in c++

Either I'm blind or std::set behaves a lot differently than std::vector when it comes to overloading the output operator. Consider the code below.

#include <set>
#include <iostream>

std::ostream& operator<<(std::ostream& os, const std::set<int>& myset) {
    for (std::set<int>::const_iterator it = myset.begin(); it < myset.end(); ++it) {
        os << *it;
        return os;
    }
}

int main () {}

If one replaces std::set by std::vector in two places and <set> by <vector> in the includes, then the code works as expected. Where is the difference? My compiler (g++) gives weird error messages such as the following.

/usr/include/c++/4.8/bits/stl_iterator.h:297:5: note: template argument deduction/substitution failed:

So even though I'm explicitly telling that I'm using std::set<int> it somehow fails and this behavior happens only for std::set .

To work in both cases you loop should be:

for (std::set<int>::const_iterator it = myset.begin(); it != myset.end(); ++it)

it < myset.end() works only for random access iterator where std::set::iterator is bidirectional.

Here you can read what bidirectional iterator provides vs random access one

Your loop condition is wrong it < myset.end(); . A std::set::iterator can't be compared with the < operator since it's not a random access iterator. The error messages in this sample are clearer about that.

To fix, compare using the != operator:

#include <set>
#include <iostream>

std::ostream& operator<<(std::ostream& os, const std::set<int>& myset) {
    for (std::set<int>::const_iterator it = myset.begin(); it !=  myset.end(); ++it) {
                                                           // ^^
        os << *it;
    }
    return os;
}

int main () {}

Working Demo


BTW you had a missing } for the for loop body in your sample.

Your code built fine after changing the loop to

for (std::set<int>::const_iterator it = myset.begin(); it != myset.end(); ++it)

Note that, in general, you cannot assume that you can less-than compare iterators.

Some containers' iterators might support this (and this might possibly also depend on the implementation), but you should really not rely on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM