Using Partial Specialization in C++11
c++, c++11, templates
Solution
The problem is that you haven't understood how selecting a class template specialization works.
Your specialization:
template<int J> struct test<int, J> {int j = J;};
does not create a template for which you only have to pass in a single int template parameter.
test<55> jj; // doesn't work because there's no template<int J> struct test
Instead what it does is create a specialization of `template<class T, int I> struct test` which will be used when the template arguments to `template<class T, int I> struct test` match the specialization, i.e. `test<int,J>`.
test<int,55> jj; // uses the specialization template<int J> struct test<int, J>
Here's the key quote from the standard:
In a type name that refers to a class template specialization, (e.g., `A<int, int, 1>`) the argument list shall match the template parameter list of the primary template. The template arguments of a specialization are deduced from the arguments of the primary template. [emphasis added]
— 14.5.5.1 [temp.class.spec.match] p4
You seem to be attempting to set `int` as a default type for `T` while simultaneously setting an independent default value for `I`. 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:
template <int I>
using test_int = test<int, I>;
This creates a template alias such that you only have to specify a value:
test_int<55> jj;
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.
Problem
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 ```