Explicit instantiations have to be at namespace scope, which means private members of classes would not normally be accessible. Without the rule you quote, this would be impossible:
class Foo
{
private:
struct Bar;
template<typename T> class Baz { };
public:
void f(); // does things with Baz<Bar>
};
// explicit instantiation declaration
extern template class Foo::Baz<Foo::Bar>;
Without that rule, I would not be able to name Foo::Bar
or even Foo::Baz
at namespace scope, because those names are private to Foo
.
Since I’m not actually using Foo::Bar
or Foo::Baz
here, just referring to their names to tell the compiler I’m instantiating the template somewhere else, there is no real access violation (although it is possible to use this rule to perform a very sneaky trick not possible otherwise).
Similarly, when I write the explicit instantiation definition in some other file, I need to be able to refer to the private names again at namespace scope.