En C ++, ¿por qué no es posible hacer amigo de una función miembro de clase de plantilla usando el tipo de plantilla de otra clase?

En otras palabras, por qué esto compila bien:

template<typename Type>
class A{
  public:
    void f();
};

class B{
  friend void A<int>::f();
};

template<>
void A<int>::f(){
  B* var = new B();
}

Si bien esto no:

template<typename Type>
class A{
  public:
    void f();
};

template<typename Type> // B is now a templated class
class B{
  friend void A<Type>::f(); // Friending is done using B templated type
};

template<>
void A<int>::f(){
  B<int>* var = new B<int>(); // var is now declared using int as its templated type
}

Para el segundo fragmento de código, el compilador (gcc 6.2, sin marcas especiales) dice:

main.cpp: In instantiation of ‘class B<int>’:
main.cpp:14:28:   required from here
main.cpp:9:15: error: prototype for ‘void A<int>::f()’ does not match any in class ‘A<int>’
   friend void A<Type>::f();
               ^~~~~~~
main.cpp:13:6: error: candidate is: void A<Type>::f() [with Type = int]
 void A<int>::f(){

Según tengo entendido, en el segundo fragmento de código, al declarar var, el compilador debe analizar la declaración de clase B, reemplazar el tipo utilizado en la declaración de amigo por int, y todo debería funcionar bien. ¿Qué me estoy perdiendo?

EDITAR: los comentarios a continuación han señalado que el segundo fragmento de código parece compilarse correctamente con clang y Visual C ++ 2015

Respuestas a la pregunta(2)

Su respuesta a la pregunta