6

I have a template class with an int and a template template parameter. Now I want to specialize a member function:

template <int I> class Default{};
template <int N = 0, template<int> class T = Default> struct Class
{
    void member();
};

// member definition
template <int N, template<int> class T> inline void Class<N, T>::member() {}

// partial specialisation, yields compiler error
template <template<int> class T> inline void Class<1, T>::member() {}

Can anyone tell me if this is possible and what I am doing wrong on the last line?

EDIT: I'd like to thank everyone for their input. As I also need a specialization for some T, I opted against the workaround suggested by Nawaz and specialized the whole class, as it had only one member function and one data member anyway.

Gabriel Schreiber
  • 2,166
  • 1
  • 20
  • 33

4 Answers4

6

You can't partially specialize a single member function, you'll have to do it for the entire class.

template <int I> class Default{};
template <int N = 0, template<int> class T = Default> struct Class
{
    void member();
};

// member definition
template <int N, template<int> class T> inline void Class<N, T>::member() {}

// partial specialization
template <template<int> class T> struct Class<1, T>
{
  void member() {}
};
Praetorian
  • 106,671
  • 19
  • 240
  • 328
3

As that is not allowed, here is one workaround:

template <int I> class Default{};

template <int N = 0, template<int> class T = Default> 
struct Class
{
    void member()
    {
         worker(int2type<N>()); //forward the call
    }
 private:
     template<int N> struct int2type {};

     template<int M>
     void worker(const int2type<M>&) //function template
     {
         //general for all N, where N != 1
     }
     void worker(const int2type<1>&) //overload 
     {
         //specialization for N == 1
     }
};

The idea is, when N=1, the function call worker(int2type<N>()) will resolve to the second function (the specialization), because we're passing an instance of the type int2type<1>. Otherwise, the first, the general, function will be resolved.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

In C++ you are not allowed to partially specialize a function; you can only partially specialize classes and structures. I believe this applies to member functions as well.

fbrereto
  • 35,429
  • 19
  • 126
  • 178
2

Check this article out: http://www.gotw.ca/publications/mill17.htm

It's pretty small, and has good code examples. It will explain the problem with patial template function specialization and show other ways around it.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255