title: Round-Robin Iterator and STL's pass-by-value policy
body: <p>I'm writing an iterator <code>round_robin_iter</code> that keeps a bunch of iterators around. Whenever <code>round_robin_iter</code> is incremented, it increments the current iterator and passes on to the next one, in a circular manner. This allows me to easily interleave items from different containers. However, with a growing number of iterators, I can no longer use STL's algorithms with <code>round_robin_iter</code> because the STL likes to pass iterators by value with is expensive in this case.</p>
  
  <p>My crude idea to solve this problem is to pass a <code>reference_wrapper&lt;rouund_robin_iter&gt;</code> by value to the STL algorithms, but this seems like a dirty hack to me. The STL surely provides some more elegant solution to my problem, doesn't it?</p>
  
  <p>EDIT: as pointed out by HolyBlackCat, <code>reference_wrapper</code> doesn't implement the right interface, so I would have to write my own wrapper around an indirection to the <code>round_robin_iter</code>...</p>
  
  <p>EDIT2: as requested, here's a rough skeleton of what the iterator may look like:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>template&lt;class Iter&gt;
  struct round_robin_iterator
  {
    using IterList = list&lt;pair&lt;Iter, Iter&gt;&gt;;
    using reference = typename iterator_traits&lt;Iter&gt;::reference;
    IterList others;
    typename IterList::iterator current = others.end();
  
    bool is_end() const { return current == others.end(); }
  
    void operator++() {
      if(!others.empty()) {
        if(++(current-&gt;first) == current-&gt;second)
          current = others.erase(current);
        else ++current;
        if(is_end()) current = others.begin();
      }
    }
  
    reference operator*() { return *(current-&gt;first); }
  
    void add_iters(const Iter&amp; _begin, const Iter&amp; _end) {
      others.emplace_back(_begin, _end);
      if(others.size() == 1) current = others.begin();
    }
  
    bool operator!=(const round_robin_iterator&amp; rr_it) const {
      if(!is_end()){
        if(!rr_it.is_end()){
          return current != rr_it.current;
        } else return true;
      } else return !rr_it.is_end();
    }
  };
  </code></pre>