I have a representation of a graph as a std::vector<std::unordered_set<unsigned>> neighbors, that is, vertices are integers, and for each vertex we keep a set of its neighbors. Thus, to walk all edges, I would do something like

for (unsigned u = 0; u < neighbors.size(); ++u)
    for (unsigned v : neighbors[u])
        if (u <= v)
            std::cout << u << ' ' << v << std::endl;

Now, I would like to be able to get the same effect from

for (auto e: g.edges())
    std::cout << e.first << ' ' << e.second << std::endl;

where g is from a class encapsulating the neighbors vector.

However, everything I tried seems extremely complicated, the best version I can come up with has 50 lines, and it's hard to see that it is correct. Is there a simple way to do this?

Here's my ugly version:

#include <iostream>
#include <unordered_set>
#include <vector>
typedef unsigned Vertex;
class Graph {
public:
    typedef std::unordered_set<Vertex> Neighbors;
    std::size_t numVertices() const { return neighbors_.size(); }
    Graph(std::size_t n = 0) : neighbors_(n) { }
    void addEdge(Vertex u, Vertex v) {
        neighbors_[u].insert(v);
        neighbors_[v].insert(u);
    }
    class EdgeIter {
        friend Graph;
    public:
        bool operator!=(const EdgeIter& other) { return u_ != other.u_; }
        void operator++() {
            do {
                ++it_;
                while (it_ == it_end_) {
                    u_++;
                    if (u_ >= neighbors_.size())
                        break;
                    it_     = neighbors_[u_].cbegin();
                    it_end_ = neighbors_[u_].cend();
                }
            } while (u_ < neighbors_.size() && *it_ < u_);
        }
        std::pair<Vertex, Ver
Edit
Report