title: Calling method with incomplete return type and my unexplainable template-workaround
body: <p>I have to post quite a bit of code in order to explain my situation. The question, however, is simple (see also at the very bottom of my post, and the last code segment):</p>
  
  <p>In <code>SubscriptProxy::is</code>, why does it compile when calling <code>this-&gt;get_element&lt;Something&gt;(parentElement);</code> but does not compile when calling <code>XYZ::get_element&lt;Something&gt;(parentElement);</code>?</p>
  
  <hr>
  
  <p>File <code>Element.hpp</code></p>
  
  <pre><code>class Element{};
  </code></pre>
  
  <p>File <code>HelperFunctions.hpp</code>:</p>
  
  <pre><code>#include "Element.hpp"
  
  namespace XYZ {
      class Something;
  
      template&lt;typename T&gt;
      T get_element(Element* e) {
      }
  
      template&lt;&gt;
      Something get_element(Element* e);
  }
  </code></pre>
  
  <p>File <code>HelperFunctions.cpp</code>:</p>
  
  <pre><code>#include "HelperFunctions.hpp"
  #include "Something.hpp"
  
  namespace XYZ {
      template&lt;&gt;
      Something get_element(Element* e) {
         // Convert Element to Something somehow
         return Something{};
      }
  }
  </code></pre>
  
  <p>File <code>SubscriptProxy.hpp</code>:</p>
  
  <pre><code>#include "HelperFunctions.hpp"
  
  namespace XYZ {
      class Something;
  
      template&lt;typename C, typename D, typename E&gt;
      class SubscriptProxy {
          C m_parent;
          E m_index; 
  
          template&lt;typename T&gt;
          T get_element(Element* e) const {
              return XYZ::get_element&lt;T&gt;(e); // call helper function
          }
  
          template&lt;typename T&gt;
          bool is(int index, Element*&amp; e) const noexcept {
              Element* parentElement;
              if (!m_parent.template is&lt;Something&gt;(m_index, parentElement)) {
                  return false;
              }
              auto d = this-&gt;get_element&lt;Something&gt;(parentElement);
              return d.template is&lt;T&gt;(index, e);
          }
      };
  }
  </code></pre>
  
  <p>And then we have <code>Something.hpp</code> and <code>Something.cpp</code>, of course. It contains an operator which returns an instance of <code>SubscriptProxy</code>:</p>
  
  <pre><code>#include "SubscriptProxy.hpp"
  #include "HelperFunctions.hpp"
  
  namespace XYZ {
      class Something {
          SubscriptProxy&lt;Something, Something, int&gt; operator[] (int index) const noexcept;
      };
  }
  </code></pre>
  
  <p>File <code>Something.cpp</code>: </p>
  
  <pre><code>#include "Something.hpp"
  
  namespace XYZ {
  SubscriptProxy&lt;Something, Something, int&gt; Something::operator[] (int index) const noexcept {
      return SubscriptProxy&lt;Something, Something, int&gt;{};
  }
  </code></pre>
  
  <hr>
  
  <p>This compiles and works fine. </p>
  
  <p>However, if I change the implementation of the <code>SubscriptProxy::is</code> method to the following:</p>
  
  <pre><code>        template&lt;typename T&gt;
          bool is(int index, Element*&amp; e) const noexcept {
              Element* parentElement;
              if (!m_parent.template is&lt;Something&gt;(m_index, parentElement)) {
                  return false;
              }
              auto d = XYZ::get_element&lt;Something&gt;(parentElement);
              return d.template is&lt;T&gt;(index, e);
          }
  </code></pre>
  
  <p>...it fails to compile with the error message: <em>Calling 'get_element' with incomplete return type 'Something'.</em></p>
  
  <p>Why?</p>