I have the following code:
template<class T, int I=44> struct test {T j = I;};
template<int J> struct test<int, J> {int j = J;};
int main()
{
test<55> jj;
std::cout << jj.j << std::endl;
return(1);
}
The compiler (clang) complains only about the line test<55> jj
I don’t understand why? Is there a work around?
And if it complains about that line, why doesn’t it complain about the second template definition?
Thanks in advance.
The message is:
enable.cpp:17:8: error: template argument for template type parameter must be a type
test<55> jj;
^~
enable.cpp:9:16: note: template parameter is declared here
template<class T, int I=44> struct test
The problem is that you haven’t understood how selecting a class template specialization works.
Your specialization:
does not create a template for which you only have to pass in a single int template parameter.
Instead what it does is create a specialization of
template<class T, int I> struct testwhich will be used when the template arguments totemplate<class T, int I> struct testmatch the specialization, i.e.test<int,J>.Here’s the key quote from the standard:
You seem to be attempting to set
intas a default type forTwhile simultaneously setting an independent default value forI. I think your intent is to be able to specify a type and a value, specify only a type and get 44 as a default value, or specify only a value and get int as a default type.Unfortunately I don’t know of a way to specify independent defaults like that. You can specify defaults (
template<class T=int, int I=44> struct test) but getting the default type will also require accepting the default value.However if you’re willing to use a second name then you can do:
This creates a template alias such that you only have to specify a value:
And this will end up using whatever specialization
test<int, I>happens to resolve to whether there’s an explicit specialization or the compiler generates an implicit one.