问题
N4567 14.5.5.1 [temp.class.spec.match]p4
In a type name that refers to a class template specialization, (e.g., A) 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.
template<class T1, class T2, int I> class A { }; // #1
template<class T, int I> class A<T, T*, I> { }; // #2
A<int, int, 1> a1; // uses #1
Does this "deduced" mean 14.8.2.5 [temp.deduct.type]?
Template arguments can be deduced in several different contexts, but in each case a type that is specified in terms of template parameters (call it
P
) is compared with an actual type (call itA
), and an attempt is made to find template argument values (a type for a type parameter, a value for a non-type parameter, or a template for a template parameter) that will makeP
, after substitution of the deduced values (call it the deduced A), compatible with A.
If it does, what is the P and A?
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 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?
What does this sentence mean?
UPDATE:
It looks @Igor Tandetnik and @R Sahu have different answers, I need more help.
回答1:
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.
回答2:
Given your template and its specialization, using:
A<int, int*, 1> a2;
will use the specialization.
For this usage,
The template parameters of the primary template are int
, int*
, and 1
.
The template parameters of the template specialization are int
, and 1
.
The arguments of the specialization, int
and 1
are deduced from the arguments of the primary template, int
, int*
, and 1
.
In this case,
P
is int
, int*
, and 1
.A
is the specialization.
I think that's the answer you are looking for.
来源:https://stackoverflow.com/questions/34552056/what-does-the-template-arguments-of-a-specialization-are-deduced-from-the-argum