This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


182. Access checking on explicit specializations

Section: 13.9.4  [temp.expl.spec]     Status: NAD     Submitter: John Spicer     Date: 8 Nov 1999

John Spicer: Certain access checks are suppressed on explicit instantiations. 13.9.3 [temp.explicit] paragraph 8 says:

The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. ]
I was surprised that similar wording does not exist (that I could find) for explicit specializations. I believe that the two cases should be handled equivalently in the example below (i.e., that the specialization should be permitted).
    template <class T> struct C {
    void f();
    void g();
    };

    template <class T> void C<T>::f(){}
    template <class T> void C<T>::g(){}

    class A {
    class B {};
    void f();
    };

    template void C<A::B>::f();    // okay
    template <> void C<A::B>::g(); // error - A::B inaccessible

    void A::f() {
    C<B> cb;
    cb.f();
    }

Mike Miller: According to the note in 13.4 [temp.arg] paragraph 3,

if the name of a template-argument is accessible at the point where it is used as a template-argument, there is no further access restriction in the resulting instantiation where the corresponding template-parameter name is used.

(Is this specified anywhere in the normative text? Should it be?)

In the absence of text to the contrary, this blanket permission apparently applies to explicitly-specialized templates as well as to implicitly-generated ones (is that right?). If so, I don't see any reason that an explicit instantiation should be treated differently from an explicit specialization, even though the latter involves new program text and the former is just a placement instruction to the implementation.

Proposed Resolution (4/02):

In 13.9.3 [temp.explicit] delete paragraph 8:

The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. ]

In 13.9 [temp.spec] add the paragraph deleted above as paragraph 7 with the changes highlighted below:

The usual access checking rules do not apply to names used to specify explicit instantiations or explicit specializations. [Note: In particular, tThe template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. ]

Rationale (October 2002):

We reconsidered this and decided that the difference between the two cases (explicit specialization and explicit instantiation) is appropriate. The access rules are sometimes bent when necessary to allow naming something, as in an explicit instantiation, but explicit specialization requires not only naming the entity but also providing a definition somewhere.