I tried to specialize a function member of a template class which is itself member of another template class.
I used the following syntax:
template<class T1>
struct A{
template<class T2>
struct B{
void f() {}
};
};
template<>
template <class T2>
void A<int>::B<T2>::f(){}
With the most recent versions of both gcc and clang I get the following error:
error: invalid use of incomplete type 'struct A<int>::B<T2>'
void A<int>::B<T2>::f(){}
It is as if the definition of the class template A<int>::B is not instantiated, only the declaration. I know that normally, if the definition is "not needed" it will not be instantiated (
[temp.inst] p.2), but in this case it is needed.
I thought this would be correct due to the following paragraphs from the standard:
- [temp.expl.spec] p.17: In an explicit specialization, it allows for some class templates to remain unspecialized (under some conditions)
- [temp.inst] p.3: It says the following: "[...] the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist [...]". I believe when I try to define a member of a template class, the definition of the member class needs to exist, therefore this definition should be instantiated.
I see that in the example present in
[temp.expl.spec] p.17 they also explicitly specialize the class template A<int>::B, so maybe there is something in the standard that states that the definition of a member template is not instantiated for an implicit specialization of the enclosing class template.
However, I do not see any difference between this and the following example, which compiles fine:
template<class T>
struct U
{
struct I
{
void f();
};
};
template<>
int U<int>::I::f() {}
It seems that in this example, the definition of U<int>::I is instantiated, therefore I can define U<int>::I::f.
Could you please tell me what in the standard makes the first example invalid and the second example valid?
Thank you.