The following code which doesn\'t compile under clang but does under gcc and VS:
template class bar;
namespace NS
{
template
I believe that clang is correct. According to [namespace.memdef]/3:
Every name first declared in a namespace is a member of that namespace. If a
friend
declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace.
In your case, the name wouldn't appear to be "first declared" by the friend
declaration. Later in that paragraph, however, emphasis mine:
If the name in a
friend
declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.
That is, this declaration:
template friend class bar;
will not look for bar
outside of namespace NS
, so it will not find your earlier declaration. As such, it declares a class template NS::bar
to be a friend
of foo
. You will have to qualify the name bar
in order for it to be found:
template friend class ::bar;
This seems related to GCC Bug 37804.