Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy do C++ templates let me circumvent incomplete types (forward declarations)?
    text
    copied!<p>I tried three iterations of the following simple program. This is a highly simplified attempt to write a container-and-iterator pair of classes, but I was running into issues with incomplete types (forward declarations). I discovered that this was in fact possible once I templatized everything - but only if I actually used the template parameter! (I realized this by looking at the <a href="http://code.google.com/p/google-sparsehash/source/browse/trunk/src/google/sparsehash/densehashtable.h" rel="nofollow noreferrer">Google sparsetable code</a>.)</p> <p>Any hints explaining why the second works while the third doesn't? (I know why the first one doesn't work - the compiler needs to know the memory layout of the container.)</p> <p>Thanks in advance.</p> <pre><code>// This doesn't work: invalid use of incomplete type. #if 0 struct container; struct iter { container &amp;c; int *p; iter(container &amp;c) : c(c), p(&amp;c.value()) {} }; struct container { int x; int &amp;value() { return x; } iter begin() { return iter(*this); } }; int main() { container c; c.begin(); return 0; } #endif // This *does* work. template&lt;typename T&gt; struct container; template&lt;typename T&gt; struct iter { container&lt;T&gt; &amp;c; T *p; iter(container&lt;T&gt; &amp;c) : c(c), p(&amp;c.value()) {} }; template&lt;typename T&gt; struct container { T x; T &amp;value() { return x; } iter&lt;T&gt; begin() { return iter&lt;T&gt;(*this); } }; int main() { container&lt;int&gt; c; c.begin(); return 0; }; // This doesn't work either. #if 0 template&lt;typename T&gt; struct container; template&lt;typename T&gt; struct iter { container&lt;int&gt; &amp;c; int *p; iter(container&lt;int&gt; &amp;c) : c(c), p(&amp;c.value()) {} }; template&lt;typename T&gt; struct container { int x; int &amp;value() { return x; } iter&lt;int&gt; begin() { return iter&lt;int&gt;(*this); } }; int main() { container&lt;int&gt; c; c.begin(); return 0; } #endif </code></pre>
 

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