George Skelton
George Skelton

Reputation: 1125

C++ Class partial specialization on non-type template parameter

I'm not sure I'm getting the terminology correct, but I think I have a class template with both a type and non-type template parameter and I want to partially specialize on the non-type parameter alone:

template<class T, int I> struct A
{
    void f();
};

template<class T> void A<T, 1>::f() {}

int main()
{
    A<int, 1> a1;
    a1.f();
}

Using Visual C++ I get error C3860: template argument list following class template name must list parameters in the order used in template parameter list and error C2976: 'A<T,I>': too few template arguments.

However if I remove the type parameter then it seems I can specialize on the non-type parameter:

template<int I> struct B
{
    void g();
};

void B<1>::g() {}

int main()
{
    B<1> b1;
    b1.g();
}

So is what I want impossible, or I'm just not doing it the right way? If it's not possible, is there an alternative?

Upvotes: 2

Views: 2173

Answers (1)

skypjack
skypjack

Reputation: 50540

Let's consider what the standard (working draft) says:

A member [...] of a class template may be explicitly specialized for a given implicit instantiation of the class template, even if the member [...] is defined in the class template definition. An explicit specialization of a member [...] is specified using the syntax for explicit specialization.

In other terms, what you are trying to do is not allowed.
That's all.


Imagine if it was, hipotetically you would have been allowed also to do this:

template<class T, int>
struct A { void f(); };

template<typename T>
void A<T, 1>::f() {}

template<>
struct A<int, 1> {};

That is, define f for a class template a specialization of which could not even have a declaration for f.
It doesn't make much sense, does it?

On the other side, consider the following member specialization:

template<>
void A<int, 1>::f() {}

It causes an instantiation of A<int, 1> that cannot be further specialized.
In other terms, you cannot do this in this case:

template<>
struct A<int, 1> {};

The presence of f is somehow guaranteed thus.

Upvotes: 2

Related Questions