Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here is some kind of funny solution using lazy evaluation. First, construct the generator object <code>enumerate_object</code>:</p> <pre><code>template&lt;typename Iterable&gt; class enumerate_object { private: Iterable _iter; std::size_t _size; decltype(std::begin(_iter)) _begin; const decltype(std::end(_iter)) _end; public: enumerate_object(Iterable iter): _iter(iter), _size(0), _begin(std::begin(iter)), _end(std::end(iter)) {} const enumerate_object&amp; begin() const { return *this; } const enumerate_object&amp; end() const { return *this; } bool operator!=(const enumerate_object&amp;) const { return _begin != _end; } void operator++() { ++_begin; ++_size; } auto operator*() const -&gt; std::pair&lt;std::size_t, decltype(*_begin)&gt; { return { _size, *_begin }; } }; </code></pre> <p>Then, create a wrapper function enumerate that will deduce the template arguments and return the generator:</p> <pre><code>template&lt;typename Iterable&gt; auto enumerate(Iterable&amp;&amp; iter) -&gt; enumerate_object&lt;Iterable&gt; { return { std::forward&lt;Iterable&gt;(iter) }; } </code></pre> <p>You can now use your function that way:</p> <pre><code>int main() { std::vector&lt;double&gt; vec = { 1., 2., 3., 4., 5. }; for (auto&amp;&amp; a: enumerate(vec)) { size_t index = std::get&lt;0&gt;(a); double&amp; value = std::get&lt;1&gt;(a); value += index; } } </code></pre> <p>The implementation above is a mere toy: it should work with both <code>const</code> and non-<code>const</code> lvalue-references as well as rvalue-references, but has a real cost for the latter though, considering that it copies the whole iterable object several times. This problem could surely be solved with additional tweaks.</p> <p>Since C++17, decomposition declarations even allow you to have the cool Python-like syntax to name the index and the value directly in the <code>for</code> initializer:</p> <pre><code>int main() { std::vector&lt;double&gt; vec = { 1., 2., 3., 4., 5. }; for (auto&amp;&amp; [index, value] a: enumerate(vec)) { value += index; } } </code></pre> <p>I don't have a C++17-compliant compiler at hand to check it, but I hope that the <code>auto&amp;&amp;</code> in the decomposition is able to infer <code>index</code> as <code>std::size_t</code> and <code>value</code> as <code>double&amp;</code>.</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.
 

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