A friend gave me the solution and I share.
According to the c++ standard :
“Each class template partial specialization is a distinct template and definitions shell be provided for the members of a template partial specialization”
That's is the reason why the code won't compile. Foo<Zoo<F>>
is a partial specialization of Foo and in this case, according to the C++ standard, the compiler doesn't use the primary template but expect for a distinct definition.
Solution 1: Define partial specialization of enclosing class
We must define first the specialization for Foo<Zoo<F>>
but if we already define it, then we actually can specialize Bar within this definition.
// partial specialization of Foo
template<typename T>
struct Foo<Zoo<T>>
{
template<typename U>
struct Bar { /* specialize declaration for Bar here */ };
/* many more members - should be define here as in the primary template of Foo */
};
This will give the desired results, but the problem is that we have to define all Foo other members again in the specialization.
Solution 2: Move declaration of nested class into a base class
// base class contains only declaration of Bar
template<typename T>
struct FooBase
{
template<typename U>
struct Bar {};
};
// Foo contains other members, but also derived from FooBase
template<typename T>
struct Foo : public FooBase<T>
{
/* many members */
};
In order to specialize Bar for when Foo is of type of Foo<Zoo<T>>
, we define the partial specialization of FooBase.
// partial specialization of FooBase
template<typename T>
struct FooBase<Zoo<T>>
{
template<typename U>
struct Bar { /* specialize declaration for Bar here */ };
};