title: C++: Is there an efficient way to use indices like pointers, syntactically?
body: <p>Here is my journey trying to get some zero-overhead syntactic convenience for a problem that I suspect pops up relatively often. I'm new to C++, so I hope that someone can offer me a better solution. All code given should compile and run under C++11. Note also that, although my solutions involve using exactly the syntax of pointers, I really am fine with just "as easy as using pointers."</p>
  
  <p>I have some code that is using a network of objects with pointers to each other, as below. (My example here is just a linked-list for simplicity, but the actual structure is more complicated - a <a href="http://www.openmesh.org/Daily-Builds/Doc/a00016.html" rel="nofollow">half-edge mesh</a>.)</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  struct Node {
    int val;
    Node* next;
  };
  
  int main()
  {
    Node* a = new Node();
    Node* b = new Node();
  
    a-&gt;val = 1;
    b-&gt;val = 2;
    a-&gt;next = b;
  
    std::cout &lt;&lt; "Sum: " &lt;&lt; a-&gt;val + a-&gt;next-&gt;val &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>For efficiency reasons, this code is being changed so that the objects are all stored in a central list, and accessed via index instead. (I understand that there are other options such as memorypools that could allow me to continue using actual pointers.)</p>
  
  <p><em>Notably,</em> I can't use iterators or pointers into the central list because the list will in general be getting modified a lot and (as I understand) pointers and iterators are likely to be invalidated.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  struct Node {
    int val;
    std::size_t next;
  };
  
  int main()
  {
    std::vector&lt;Node&gt; nodeList {2};
    std::size_t a = 0;
    std::size_t b = 1;
  
    nodeList[a].val = 1;
    nodeList[b].val = 2;
    nodeList[a].next = b;
  
    std::cout &lt;&lt; "Sum: " 
              &lt;&lt; nodeList[a].val + nodeList[nodeList[a].next].val
              &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>Obviously, there's a syntactic cost to this change. In Scala, I could get around that with implicits. In C++, the most obvious thing I can think to do is create a wrapper object that knows both the index and the array, like this:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  template&lt;typename T, typename AofT = std::vector&lt;T&gt;&gt;
  struct IndexPtr {
    std::size_t index;
    AofT* collection;
  
    IndexPtr() = default;
    IndexPtr(std::size_t index, AofT&amp; collection)
      : index(index), collection(&amp;collection) 
    { /* no more initialization to do */ }
  
    T&amp; operator*() { return (*collection)[index]; }
    T* operator-&gt;() { return &amp;(*collection)[index]; }
  };
  
  struct Node {
    int val;
    IndexPtr&lt;Node, std::vector&lt;Node&gt;&gt; next;
  };
  
  int main()
  {
    std::vector&lt;Node&gt; nodeList {2};
    auto a = IndexPtr&lt;Node&gt;(0, nodeList);
    auto b = IndexPtr&lt;Node&gt;(1, nodeList);
  
    a-&gt;val = 1;
    b-&gt;val = 2;
    a-&gt;next = b;
  
    std::cout &lt;&lt; "Sum: " &lt;&lt; a-&gt;val + a-&gt;next-&gt;val &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>However, now I'm storing an additional pointer with every index just for syntactic convenience. Unacceptable, especially since I have an eye to performance. So the only other thing I can think to do is kind of hackily simulate implicit parameters with a static class member:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  template&lt;typename T, typename AofT = std::vector&lt;T&gt;&gt;
  struct IndexPtr {
    static AofT* collection;
  
    std::size_t index;
  
    IndexPtr() = default;
    IndexPtr(std::size_t index) : index(index) {}
  
    T&amp; operator*() { return (*collection)[index]; }
    T* operator-&gt;() { return &amp;(*collection)[index]; }
  };
  
  template&lt;typename T, typename AofT&gt;
  AofT* IndexPtr&lt;T, AofT&gt;::collection = nullptr;
  
  struct Node {
    int val;
    IndexPtr&lt;Node, std::vector&lt;Node&gt;&gt; next;
  };
  
  int main()
  {
    std::vector&lt;Node&gt; nodeList {2};
    IndexPtr&lt;Node&gt;::collection = &amp;nodeList;
  
    auto a = IndexPtr&lt;Node&gt;(0);
    auto b = IndexPtr&lt;Node&gt;(1);
  
    a-&gt;val = 1;
    b-&gt;val = 2;
    a-&gt;next = b;
  
    std::cout &lt;&lt; "Sum: " &lt;&lt; a-&gt;val + a-&gt;next-&gt;val &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>And that's the best that I've come up with, and it's a bit unsatisfying.</p>
  
  <ul>
  <li>Everything breaks horribly if you forget to initialize the <code>collection</code> variable before using any <code>IndexPtr</code>s.</li>
  <li>You can't have <code>IndexPtr</code>s using different arrays at the same time (easily), but I'm mostly OK with that.</li>
  <li>I don't know if there are any particular performance penalties to this approach. </li>
  </ul>
  
  <p>Thoughts?</p>