Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes you can, it just take some massaging ;)</p> <p>The trick is to use composition: instead of iterating over the container directly, you "zip" it with an index along the way.</p> <p>Specialized zipper code:</p> <pre><code>template &lt;typename T&gt; struct iterator_extractor { typedef typename T::iterator type; }; template &lt;typename T&gt; struct iterator_extractor&lt;T const&gt; { typedef typename T::const_iterator type; }; template &lt;typename T&gt; class Indexer { public: class iterator { typedef typename iterator_extractor&lt;T&gt;::type inner_iterator; typedef typename std::iterator_traits&lt;inner_iterator&gt;::reference inner_reference; public: typedef std::pair&lt;size_t, inner_reference&gt; reference; iterator(inner_iterator it): _pos(0), _it(it) {} reference operator*() const { return reference(_pos, *_it); } iterator&amp; operator++() { ++_pos; ++_it; return *this; } iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; } bool operator==(iterator const&amp; it) const { return _it == it._it; } bool operator!=(iterator const&amp; it) const { return !(*this == it); } private: size_t _pos; inner_iterator _it; }; Indexer(T&amp; t): _container(t) {} iterator begin() const { return iterator(_container.begin()); } iterator end() const { return iterator(_container.end()); } private: T&amp; _container; }; // class Indexer template &lt;typename T&gt; Indexer&lt;T&gt; index(T&amp; t) { return Indexer&lt;T&gt;(t); } </code></pre> <p>And using it:</p> <pre><code>#include &lt;iostream&gt; #include &lt;iterator&gt; #include &lt;limits&gt; #include &lt;vector&gt; // Zipper code here int main() { std::vector&lt;int&gt; v{1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto p: index(v)) { std::cout &lt;&lt; p.first &lt;&lt; ": " &lt;&lt; p.second &lt;&lt; "\n"; } } </code></pre> <p>You can see it at <a href="http://ideone.com/rAcaZ">ideone</a>, though it lacks the for-range loop support so it's less pretty.</p> <p><strong>EDIT:</strong></p> <p>Just remembered that I should check Boost.Range more often. Unfortunately no <code>zip</code> range, but I did found a perl: <a href="http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/adaptors/reference/indexed.html"><code>boost::adaptors::indexed</code></a>. However it requires access to the iterator to pull of the index. Shame :x</p> <p>Otherwise with the <a href="http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/ranges/counting_range.html"><code>counting_range</code></a> and a generic <code>zip</code> I am sure it could be possible to do something interesting...</p> <p>In the ideal world I would imagine:</p> <pre><code>int main() { std::vector&lt;int&gt; v{1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto tuple: zip(iota(0), v)) { std::cout &lt;&lt; tuple.at&lt;0&gt;() &lt;&lt; ": " &lt;&lt; tuple.at&lt;1&gt;() &lt;&lt; "\n"; } } </code></pre> <p>With <code>zip</code> automatically creating a view as a range of tuples of references and <code>iota(0)</code> simply creating a "false" range that starts from <code>0</code> and just counts toward infinity (or well, the maximum of its type...).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload