Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is partial specialization of a nested class template allowed, while complete isn't?

    template<int x> struct A {                                                                                                             template<int y> struct B {};.                                                                                                      template<int y, int unused> struct C {};                                                                                       };                                                                                                                                  template<int x> template<>      struct A<x>::B<x> {}; // error: enclosing class templates are not explicitly specialized      template<int x> template<int unused>      struct A<x>::C<x, unused> {}; // ok 

So why is the explicit specialization of a inner, nested class (or function) not allowed, if the outer class isn't specialized too? Strange enough, I can work around this behaviour if I only partially specialize the inner class with simply adding a dummy template parameter. Makes things uglier and more complex, but it works.

I would consider complete specializations as a subset of partial specializations - especially because you can express every complete specialization as a partial with adding a dummy parameter. So this disambiguation between partial and full specialization doesn't really make sense for me.

Unfortunatly nobody at comp.std.c++ dared to answer, so I am putting it up here again with a bounty.

Note: I need this feature for recursive templates of the inner class for a set of the outer class and the specialization of the inner parameter does depend on the outer template parameter.

like image 857
Gunther Piez Avatar asked Mar 29 '10 12:03

Gunther Piez


2 Answers

My guess as to why this happens: complete specializations are no longer "template classes/functions", they are are "real" classes/methods, and get to have real (linker-visible) symbols. But for a completely-specialized template inside a partially-specialized one, this would not be true. Probably this decision was taken just to simplify the life of compiler-writers (and make life harder for coders, in the process :P ).

like image 137
Virgil Avatar answered Sep 28 '22 21:09

Virgil


C++ Standard explicitly prohibits full specialization of member template classes in first case. According to 14.7.3/18:

In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.

like image 21
Kirill V. Lyadvinsky Avatar answered Sep 28 '22 20:09

Kirill V. Lyadvinsky