BananyaDev
BananyaDev

Reputation: 623

Partial template specialization of non type argument not allowed

The following code does not work, it gives an error saying "Too few template arguments for struct foo" and I do not understand why. To me it seems like the code should be valid. I found a snippet from CPP reference here in the section "The argument list", paragraph 4 which might explain why it does not work but I don't understand it.

template<int a, int b, int c> struct foo { };
template<int a> struct foo<a, 0, 0> { };

int main()
{
    foo<1> f;
}

Upvotes: 2

Views: 1622

Answers (3)

HolyBlackCat
HolyBlackCat

Reputation: 96013

It's not how template specialization works. You have* to specify all arguments.
*(Except when you have default arguments (see @StoryTeller's answer), or when C++17 argument deduction kicks in, but both don't apply here.)

Here's a small demo:

#include <iostream>

template<int a, int b, int c> struct foo { void bar() {std::cout << "1\n";} };
template<int a> struct foo<a, 0, 0> { void bar() {std::cout << "2\n";} };

int main()
{
    foo<1, 2, 3> a;
    foo<4, 0, 0> b;
    a.bar(); // prints 1
    b.bar(); // prints 2
}

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 172864

Note that the primary template takes 3 template parameters. Then you have to specify all of them. e.g.

foo<1, 0, 0> f; // the partial specification is used

Upvotes: 1

It's allowed. But your template takes 3 parameters. Specializing it doesn't magically turn it into a 1 parameter template.

You can make the other parameter have default arguments, however:

template<int a, int b = 0, int c = 0> struct foo { char _[1] ; };
template<int a> struct foo<a, 0, 0> { char _[10] ;};

int main() {
    static_assert(sizeof(foo<1>) > sizeof(foo<1, 1, 1>), "");
    return 0;
}

Upvotes: 4

Related Questions