typename must be used for dependent name resolution as described in 14.6 [temp.res].
An elaborated-type-specifier with the class-key present is required ("shall be used") in a friend declaration for a class. 11.4.2 [class.friend] and 7.1.5.3.1 [decl.type.elab].
However, an elaborated-type-specifier cannot be a typedef-name. 3.4.4.2 [basic.lookup.elab].
Lastly, the is no need for registration since "a definition for a static data member may be provided in a namespace scope enclosing the definition of the static member's class template." 14.5.1.3.1 [temp.static].
like songs and courses: it's difficult to guarantee that all references
to them are updated if they're deleted or reallocated, which is a brittleness
that leads to obscure bugs.
A general fix for this is to avoid storing pointers to objects, and
to use IDs instead; for example, SongID to reference a song (which
tags by directory). This leads to an efficiency problem: searching
a map<RString> is much more expensive. We need a robust way to
cache the results.
Implement CachedObject<T>, CachedObjectPointer<T>. This implements
caching pointers to objects, negative caching, clearing cache when objects
are deleted, and clearing negative cache when objects are created.