All standard references below refers to N4659: March 2017 post-Kona working draft/C++17 DIS.
Consider the following class template A
and class B
which private defines a nested class C
and enum class E
:
template<typename T, typename U>
class A {};
class B {
class C {};
enum class E {};
};
According to [temp.explicit]/12:
The usual access checking rules do not apply to names used to specify explicit instantiations. [...]
we may refer e.g. to private types such as B::C
and B::E
in the template argument list when specifying explicit instantiations:
// OK: explicit instantiation definition.
template class A<B::C, B::E>;
I'm trying to find the similar segment in the standard that specifies whether the same waiving of access right restrictions when specifying the template argument list for (partial and particularly explicit/full) specializations.
// Partial specialization.
template<typename U>
class A<B::C, U> {};
// Explicit(/full) specialization.
template<>
class A<B::C, B::E> {};
The partial specialization fails to compile in Clang
error: 'C' is a private member of 'B'
whereas GCC accepts it. Possibly this is due to different instantiation rules between GCC and Clang. Both GCC and Clang accepts the explicit(/full) specialization.
I'm suspecting the explicit(/full) specialization is well-formed whereas the partial specialization is ill-formed (implicitly due to default rules). However, for the former, I have not been able to find a statement similar to that of [temp.explicit]/12 in [temp.expl.spec].
Question
- Where, in the standard, is it specified (implicitly or explicitly) that the usual access checking rules do not apply for the template argument list for (particularly explicit/full) specializations?
template<>
). I've will update the wording of the question accordingly. Do you happen to also know the answer, whether we may or may not legally waive access checking rules for explicit(/full) specializations? – dfrib