title: Calling template methods in template classes
body: <p>I'm attempting to figure out why some code that I have won't compile and I done a fair bit of reduction an anonymizing to end up with this example:</p>
  
  <pre><code>#define NULL ((void*)0)
  template&lt;typename T&gt;
  class a {
  public:
    template&lt;bool b&gt;
    T * amem() {
      return NULL;
    }
  };
  
  template&lt;typename T&gt;
  class b {
  public:
    a&lt;T&gt;* ap;
  
    template &lt;bool b&gt;
    T * m() {
      return ap-&gt;amem&lt;b&gt;();
    }
  };
  
  int main()
  {
    return 0;
  }
  </code></pre>
  
  <p>Depending on the compiler that I use <em>and the names of the variables</em> I get different errors.  They are all centered around this line, though:</p>
  
  <pre><code>    return ap-&gt;amem&lt;b&gt;();
  </code></pre>
  
  <p>Compiling using clang++ [Apple clang version 4.0 (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)], I get the following message:</p>
  
  <pre><code>tmp.cpp:18:26: error: expected expression
        return ap-&gt;amem&lt;b&gt;();
                           ^
  1 error generated.
  </code></pre>
  
  <p>Compiling using g++ [i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1], I get the following message:</p>
  
  <pre><code>tmp.cpp: In member function ‘T* b&lt;T&gt;::m()’:
  tmp.cpp:18: error: expected primary-expression before ‘&gt;’ token
  tmp.cpp:18: error: expected primary-expression before ‘)’ token
  </code></pre>
  
  <p>Mysteriously (to me, anyway).  If I change the name of amem to m, I no longer get any errors from g++, but I get the same error from clang++.</p>
  
  <p>I'm sure there is something here that I just don't understand?  Does anyone know what expression clang and gcc are looking for?  Does anyone know how to solve this problem?</p>
  
  <p>If this is a compiler bug (seems doubtful), does anyone know any workarounds that don't involve converting amem into a function with a bool parameter (rather than a template)?  I've done this already and I can confirm that this works around the issue, but this is inside a hot loop and the code that is switched on by b is a memory allocation that probably shouldn't be in a hot loop.</p>