c++templatespartial-specialization

Partial class template specialization not considered neither by GCC or CLang


Given this simple example:

template<class T, class TT>
class make_it { };

template<class T>
class make_it<T, T*> { };

make_it<int>

I would expect to be able to use it both as make_it<type, type> and make_it<type> but the example template invocation at the end of the code does not compile.

When trying to compile it with GCCI get:

test-partial-spec.cpp:8:12: error: wrong number of template arguments (1, should be 2)

Same with CLang:

test-partial-spec.cpp:8:1: error: too few template arguments for class template 'make_it'

What puzzles me more is that when I take the example from here:

template<class T1, class T2, int I>
class A {};

template<class T, int I>
class A<T, T*, I> {};

A<int, 3>

It does not compile as well:
GCC:

test-partial-spec.cpp:18:9: error: wrong number of template arguments (2, should be 3)
   18 | A<int, 3>
      |         ^

CLang:

test-partial-spec.cpp:18:8: error: template argument for template type parameter must be a type
A<int, 3>
       ^

This might look like an easy question, but how do I define a partial specialization with less parameters than the generic template?


Solution

  • You can't make a partial specialization which takes fewer parameters than the primary template: they have to take the same amount.

    Your partial specialization lets you customize the behaviour of make_if for the case where the second template argument is a pointer to the first.

    If you instead want to default the second parameter to be a pointer to the first template argument, such that make_it<int> is the same as make_it<int, int*> you can do this:

    template<class T, class TT = T*>
    class make_it { };
    

    Or to make it work in some corner cases, like when T is a reference:

    template<class T, class TT = std::add_pointer_t<T>>
    class make_it { };