Hacer una clase indefinida como amigo y definirla más tarde

Haciendo un amigo desconocido

template<typename T>
class List
{
protected:

    class a {
        int x;
        int y;
    private:
        friend class b;  // <------------ Why this is not an error? 
    };

    template <typename U > class b {  //If that is not a error this should be an error
        int z;
        U y;
    };

    public:
        List() {
            a* ptr = (a *)new unsigned char[sizeof(a)];
        }
};

int main() {
    List<int>  mylist;
}

Vaya a través de este enlace, tengo mis preguntas como comentarios en el código. Estoy tratando de hacer que otra clase sea amiga de mi clase. Pero esa clase no se sabe a la hora de hacer amigos. ¿Cuál es la regla de C ++ que lo permite? Más tarde, estoy definiendo esa clase de tal manera que sea incompatible con la declaración de amigo. ¿Por qué eso no arroja un error? Gracias

Respuestas a la pregunta(3)

Su respuesta a la pregunta