Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specialize member of template class with template template parameter

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.

like image 235
Gabriel Schreiber Avatar asked Sep 26 '11 17:09

Gabriel Schreiber


4 Answers

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() {}
};
like image 76
Praetorian Avatar answered Oct 05 '22 14:10

Praetorian


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.

like image 24
Nawaz Avatar answered Oct 05 '22 14:10

Nawaz


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.

like image 27
fbrereto Avatar answered Oct 05 '22 14:10

fbrereto


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.

like image 43
John Humphreys Avatar answered Oct 05 '22 16:10

John Humphreys