Why do the usual access control checking applies to names used to specify explicit instantiation when accessed through template parameters?

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.

Leave a Comment