Reputation: 623
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
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
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
Reputation: 170044
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