title: make another instatiation's friend of a template class
body: <pre><code>template &lt;typename T&gt; class Foo;    
  template &lt;typename T&gt; int g(Foo&lt;T&gt; const&amp;);
  
  template &lt;typename T&gt; class Foo
  {
  public:
      template &lt;typename U&gt; int f(Foo&lt;U&gt; const&amp; p) const { return p.m; }
  
      // which friend declaration will allow the above function to compile? The
      // next one doesn't work.
      template &lt;typename U&gt; friend void Foo&lt;U&gt;::template f&lt;T&gt;(Foo&lt;T&gt; const&amp;) const;
  
      // while this one work for g().
      friend int g&lt;T&gt;(Foo&lt;T&gt; const&amp;);
  
  private:
      int m;
  };
  
  template &lt;typename T&gt; int g(Foo&lt;T&gt; const&amp; p) { return p.m; }
  
  // Let's call them
  void bar()
  {
      Foo&lt;int&gt; fi;
      Foo&lt;double&gt; fd;
      fd.f(fi);
      g(fi);
  }
  </code></pre>
  
  <p>The above doesn't compile with g++ nor Como.  g() is here to show what I would like to do with f().</p>
  
  <p>For instance, here are g++ messages:</p>
  
  <pre><code>foo.cpp:11: error: invalid use of template-id ‘f&lt;T&gt;’ in declaration of primary template
  foo.cpp: In member function ‘int Foo&lt;T&gt;::f(const Foo&lt;U&gt;&amp;) const [with U = int, T = double]’:
  foo.cpp:27:   instantiated from here
  foo.cpp:17: error: ‘int Foo&lt;int&gt;::m’ is private
  foo.cpp:7: error: within this context
  </code></pre>
  
  <p>and como's one:</p>
  
  <pre><code>"ComeauTest.c", line 11: error: an explicit template argument list is not allowed on
            this declaration
        template &lt;typename U&gt; friend void Foo&lt;U&gt;::template f&lt;T&gt;(Foo&lt;T&gt; const&amp;) const;
                                          ^
  
  "ComeauTest.c", line 7: error: member "Foo&lt;T&gt;::m [with T=int]" (declared at line 17)
            is inaccessible
        template &lt;typename U&gt; int f(Foo&lt;U&gt; const&amp; p) const { return p.m; }
                                                                      ^
            detected during instantiation of "int Foo&lt;T&gt;::f(const Foo&lt;U&gt; &amp;)
                      const [with T=double, U=int]" at line 27
  
  2 errors detected in the compilation of "ComeauTest.c".
  </code></pre>
  
  <p>Variants suggested by the error messages didn't either.</p>
  
  <p>BTW, I know of the obvious work around</p>
  
  <pre><code>template &lt;typename U&gt; friend class Foo&lt;U&gt;;
  </code></pre>
  
  <p>Edit:</p>
  
  <p>14.5.4/5 (of n3225, 14.5.3/6 of C++98 is similar but the following text is clearer in n3225) starts by</p>
  
  <blockquote>
    <p>A member of a class template may be declared friend of a non-template class...</p>
  </blockquote>
  
  <p>which could imply that a member of a class template may not be declared friend of a template class but my first interpretation would that this sentence was an introduction for the following explanations (mainly they apply to any specialisation, explicit or not, given that the prototype is correct).</p>