16

Possible Duplicate:
Specialization of templated member function in templated class

template <class T>    
class MyClass
{
   template <int N>
   void func() {printf("unspecialized\n");}
};
template<class T>
template<>
MyClass<T>::func<0>()
{
   printf("specialzied\n");
}

This does not work. Is it possible to specialize a template method of an template class?

Community
  • 1
  • 1
Alexander Vassilev
  • 1,399
  • 13
  • 23
  • 1
    You should add the error message you get, since "does not work" really doesn't tell us much. – sth Apr 16 '12 at 17:23

1 Answers1

27

It cannot be done as requested. For some reason (I'm not sure about the rationale) explicit (i.e full) specialization of a member template is only allowed when the enclosing class is also explicitly (i.e fully) specialized. This requirement is explicitly spelled out in the language standard (see 14.7.3/18 in C++98, C++03 and 14.7.3/16 in C++11).

At the same time, partial specializations of member class templates are allowed, which in many cases can be used as a workaround (albeit an ugly one). But, obviously, it is only applicable to member class templates. When it comes to member function templates, an alternative solution has to be used.

For example, a possible workaround is to delegate the call to a static member of a template class and specialize the class instead (which is often recommended as a better idea than specialization of function templates http://www.gotw.ca/publications/mill17.htm)

template <class T>    
class MyClass
{
   template <int N, typename DUMMY = void> struct Func {
     static void func() { printf("unspecialized\n"); }
   };

   template <typename DUMMY> struct Func<0, DUMMY> {
     static void func() { printf("specialized\n"); }
   };

   template <int N> void func() { Func<N>::func(); }
};
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Thanks, that's what I found out as well - I have to specialize the containing class. Your solution with using a class for the function is maybe the best solution in my case – Alexander Vassilev Apr 16 '12 at 17:46
  • Do you have a reference for this requirement? I've been reading through the part(s) of the standard that look relevant (starting around §14.7.3) and haven't been able to find this requirement. – Jerry Coffin Apr 16 '12 at 17:50
  • 2
    @Jerry : C++11 §14.7.3/16: "*... except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.*" – ildjarn Apr 16 '12 at 18:00
  • 1
    @Jerry Coffin: In C++98 and C++03 it was stated in 14.7.3/18. In C++11 it was relocated to 14.7.3.16, as **ildjarn** noted. – AnT stands with Russia Apr 17 '12 at 02:12
  • @AndreyT: Yeah, the rearrangement was what got me -- I read down a ways in the '03 standard, sort of gave up before I got to it, and decided to look in the new standard instead. I looked at some of the first paragraphs, and they seemed pretty much identical, so I more or less skipped down to about where I'd left off. Murphy still being in charge, that was around paragraph 17... – Jerry Coffin Apr 17 '12 at 03:11
  • 6
    I am now convinced that c++ is broken beyond repair... – Zsolt Szatmari Dec 01 '15 at 13:08
  • @AnT Hello. The paragraph that you mention in your answer contains the following, as quoted by ildjarn: "except that the declaration shall not explicitly specialize a **class** member template if its enclosing class templates are not explicitly specialized as well.". Doesn't this exception refer only to **class templates** and therefore specializing a function member template without specializing its enclosing class template should be legal? Thank you. – user42768 Apr 20 '18 at 16:13