First, it should be noted that these rules are meant more as if you were implementing a C++ parser (like a compiler), so if one of these specific rules is not met, then the program should be non-conforming (and an error generated). So in the paragraph you mention:
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.
Think of it to mean that if the source being parsed does not meet the restrictions of these paragraphs, it is non-conforming so generate an error.
Directly answering the main question of:
What does “The template arguments of a specialization are deduced from the arguments of the primary template” mean?
14.5.5
is about template partial specializations, 14.5.5.1
is specifically about matching the partial specialization and paragraph 4 (where the sentence is from) is just saying that the template arguments passed to a template must match those of a specialized template.
The last sentence of paragraph 4 (the one in question), is simply saying that the arguments passed in are deduced based on the main template.
It gives an example of A<int, int, 1>
when talking about this paragraph, and it's referring to the other template specializations in the example it gives in 14.5.5.1
(separated for easier reading):
// #1 (main template)
template<class T1, class T2, int I>
class A
{ };
// #2
template<class T, int I>
class A<T, T*, I>
{ };
// #3
template<class T1, class T2, int I>
class A<T1*, T2, I>
{ };
// #4
template<class T>
class A<int, T*, 5>
{ };
// #5
template<class T1, class T2, int I>
class A<T1, T2*, I>
{ };
So, given the following code:
A<int, int, 1> a1;
A<int, char*, 5> a2;
A<int, int, 2.0f> a3;
A<int*> a4;
a1
will compile fine, and template #1
will be used (since it matches exactly to that specialization), so template #1
will compile to the following:
template<
class T1 = int,
class T2 = int,
int I = 1>
class A
{ };
a2
will compile fine as well and template #4
will be used as such:
template<
class T = char>
class A<int, T*, 5>
{ };
a3
, however, doesn't match any of the template specializations, and a conforming compiler will generate an error when compiling a3
since the types of int
do not match type of float
; that is, a3
would generate a template of the following type:
template<
class T1 = int,
class T2 = int,
int I = 2.0f>
class A
{ };
And thus should generate an error since an int
is not a float
. Lastly, a4
will not compile as well since it only has 1 template argument and all template specializations for A
take 3 arguments.
Continuing with your questions:
Does this "deduced" mean 14.8.2.5 [temp.deduct.type]?
Yes and no, deduced
is referring to the whole of 14.8.2 Template argument deduction
, where paragraph 2 states:
When an explicit template argument list is specified, the template arguments must be compatible with the template parameter list and must result in a valid function type as described below; otherwise type deduction fails.
Where described below
has additional points not posted here for brevities sake.
However, 14.8.2.5
specifically refers to how to deduce the type in a conforming way, and if a template specialization can't be deduced this way then it should fail (i.e. compiler should generate an error).
If it does, what is the P and A?
The P
and A
in this sentence are just place holder values to use for the rest of the text.
Specifically what it's trying to get at is that P
is to mean a template argument and A
is to mean an actual type that can be used, like an int
or std::string
or a user defined type like a class
, struct
or typedef
, or function.
Take this code for example:
#1
template < class T >
struct A {
T val;
};
#2
template<>
struct A<double>
{
double val;
};
int main() {
A<int> a1; // uses #1
A<double> a2; // uses #2
A<someVal> a3; // uses #1 but generate error since `someVal` is invalid type
}
In this code, the P
val would be the template argument of class T
and the A
val would be int
for a1
, double
for a2
and someVal
for a3
. A conforming compiler should generate an error for a3
since there is not type that will make P, after substitution of the deduced values (call it the deduced A), compatible with A
, since someVal
is not a valid type.
Using the example A<int, int, 2.0f> a3;
from above, since there were no templates defined that could take the last argument (the 2.0f
), the P
val here is int
and the A
val is 2.0f
; since 2.0f
is not an int
, this template deduction fails and an error is generated.
You also asked:
The template arguments of a specialization means the actual template arguments of the primary template int, int, 1 or the template arguments of the partial specialization T, T*, I or other?
The template arguments of a specialization
is referring to the arguments passed into the template, so in A<int, int, 1>
the template arguments of this specializations are int
, int
and 1
.
the arguments of the primary template means the actual template arguments of the primary template int, int, 1 or the implicitly template arguments of the primary template T1, T2, I or other?
the arguments of the primary template
are referring to the primary template itself, so in the A
example above, the primary template would be template<class T1, class T2, int I> class A { };
I hope that can help.
A
would beint
,int
and1
.P
would beT
,T*
andI
(as usual, the deduction for each argument is performed separately). In this case, the deduction fails for the second argument (T
inT*
can't be deduced fromint
), and so the primary template, rather than specialization, is instantiated. – Igor Tandetnik