While trying to get some old software to compile with clang, I encountered some code similar to the following:
class OuterClass {
private:
template <class T>
class InnerClass {};
};
template <class T>
class OtherClass {};
template <class T>
class OtherClass<OuterClass::InnerClass<T>> {};
My understanding of this code is that the template class OtherClass is specialized for instantiations of the private inner template class OuterClass::InnerClass.
g++-10 (version 10.2.0) seems to compile this code without any errors or warnings, but clang++-10 (version 10.0.0) complains that "'InnerClass' is a private member of 'OuterClass'" at the template specialization.
Of course, I could make InnerClass public, but, since InnerClass is private in the original code, I think this solution would not be ideal. Is there a way I could allow InnerClass to be used in the specialization of OtherClass only (perhaps with some clever use of friend)?
I thought maybe I could do something like this, (which is similar to the approach taken in this answer to a similar question but I get an error stating that "partial specialization cannot be declared as a friend."
template <typename T>
friend class OtherClass<InnerClass<T>>;
The posted code appears to compile under
gcconly because the template is never actually instantiated (and no code is generated), but fails if attempting to instantiate it.For
OtherClass<InnerClass<T>>instantiations to work, the inner type needs to be made accessible to the template classes. One way to do it is by declaring those as a public type inOuterClass.The above assumes that
OuterClassknows about theOtherClasstemplates that it wants to exposeInnerClassto. Probably a reasonable assumption in the context, otherwiseInnerClasscould simply be made public and accessible to all other classes/templates indiscriminately.