当参数是函数参数包时,在部分排序期间推导模板参数
Deducing template arguments during partial ordering when parameters are function parameter pack
N4527 14.8.2.4 [temp.deduct.partial]
3 The types used to determine the ordering depend on the context in which the partial ordering is done:
(3.1) — In the context of a function call, the types used are those function parameter types for which the function call has arguments.
(3.2) — In the context of a call to a conversion function, the return types of the conversion function templates are used.
(3.3) — In other contexts (14.5.6.2) the function template’s function type is used.
4 Each type nominated above from the parameter template and the corresponding type from the argument
template are used as the types of P
and A
.
8 If A
was transformed from a function parameter pack and P
is not a parameter pack, type deduction fails.
Otherwise, using the resulting types P
and A
, the deduction is then done as described in 14.8.2.5. If P
is a function parameter pack, the type A
of each remaining parameter type of the argument template is
compared with the type P
of the declarator-id of the function parameter pack. Each comparison deduces
template arguments for subsequent positions in the template parameter packs expanded by the function
parameter pack. If deduction succeeds for a given type, the type from the argument template is considered
to be at least as specialized as the type from the parameter template.
[ Example:
template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more
// specialized than the variadic templates #1 and #2
为什么 f(1, 2, 3);
调用 #2?
我需要更多详细信息,包括:
1 是哪个语境?
2 转化的from是什么?
例如#1 的转换形式是 void (U)
, void (U...)
或其他形式?(U
表示唯一类型)
14.5.6.2 [temp.func.order]/p3
To produce the transformed template, for each type, non-type, or template template parameter (including
template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively
and substitute it for each occurrence of that parameter in the function type of the template.
3 推导中使用的P
和A
有哪些类型?例如
template <class T> void f(T);
int a = 1;
f(a);//P = T, A = int
Why f(1, 2, 3);
calls #2?
你的问题有很多问题(请每个问题一个问题!),所以我会坚持这一点。首先,我们执行模板推导。 #3 失败,但#1 和#2 成功:
template<class... Args>
void f(Args... args); // #1, with Args = {int, int, int}
template<class T1, class... Args>
void f(T1 a1, Args... args); // #2, with T1 = int, Args = {int, int}
这两个函数的值都取三个 int
,因此重载解析中的所有正常决胜局都无法解决歧义。所以我们到了最后一个:
Given these definitions, a viable function F1
is defined to be a better function than another viable function F2
if for all arguments i
, ICSi(F1
) is not a worse conversion sequence than ICSi(F2
), and then
— [...]
— F1
and F2
are function template specializations, and the function template for F1
is more specialized
than the template for F2
according to the partial ordering rules described in 14.5.6.2.
规则是:
步骤 1:合成类型 [temp.func.order]:
To produce the transformed template, for each type, non-type, or template template parameter (including
template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively
and substitute it for each occurrence of that parameter in the function type of the template.
所以我们有:
void f(Pack1... args); // #1
void f(U2 a1, Pack2... args); // #2
步骤 2:按照 [temp.deduct.partial] 中的描述执行推导。我们所在的上下文是函数调用,因此我们使用函数调用具有参数的类型。
首先,我们尝试从#1 推导出#2。也就是说,我们尝试将 (T1, Args...
) 与 (Pack1...)
进行匹配。那么第一部分就是P = T1, A = Pack1...
。我们有:
If A was transformed from a function parameter pack and P is not a parameter pack, type deduction fails.
所以从#1 推导出#2 失败了,所以参数 Args...
至少不像 T1, Args...
那样专业。
接下来,我们尝试从#2 推导出#1。也就是说,我们尝试将 (Args...)
与 (U2, Pack2...)
进行匹配。成功了,所以 T1, Args...
至少和 Args...
.
一样专业
由于#2 至少与#1 一样专业,而#1 至少不如#2 专业,我们可以说#2 更专业:
Function template F
is at least as specialized as function template G
if, for each pair of types used to
determine the ordering, the type from F
is at least as specialized as the type from G
. F
is more specialized
than G
if F
is at least as specialized as G
and G
is not at least as specialized as F
.
首选更专业的模板,因此我们调用#2。
N4527 14.8.2.4 [temp.deduct.partial]
3 The types used to determine the ordering depend on the context in which the partial ordering is done:
(3.1) — In the context of a function call, the types used are those function parameter types for which the function call has arguments.
(3.2) — In the context of a call to a conversion function, the return types of the conversion function templates are used.
(3.3) — In other contexts (14.5.6.2) the function template’s function type is used.
4 Each type nominated above from the parameter template and the corresponding type from the argument template are used as the types of
P
andA
.8 If
A
was transformed from a function parameter pack andP
is not a parameter pack, type deduction fails. Otherwise, using the resulting typesP
andA
, the deduction is then done as described in 14.8.2.5. IfP
is a function parameter pack, the typeA
of each remaining parameter type of the argument template is compared with the typeP
of the declarator-id of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template. [ Example:
template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more
// specialized than the variadic templates #1 and #2
为什么 f(1, 2, 3);
调用 #2?
我需要更多详细信息,包括:
1 是哪个语境?
2 转化的from是什么?
例如#1 的转换形式是 void (U)
, void (U...)
或其他形式?(U
表示唯一类型)
14.5.6.2 [temp.func.order]/p3
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.
3 推导中使用的P
和A
有哪些类型?例如
template <class T> void f(T);
int a = 1;
f(a);//P = T, A = int
Why
f(1, 2, 3);
calls #2?
你的问题有很多问题(请每个问题一个问题!),所以我会坚持这一点。首先,我们执行模板推导。 #3 失败,但#1 和#2 成功:
template<class... Args>
void f(Args... args); // #1, with Args = {int, int, int}
template<class T1, class... Args>
void f(T1 a1, Args... args); // #2, with T1 = int, Args = {int, int}
这两个函数的值都取三个 int
,因此重载解析中的所有正常决胜局都无法解决歧义。所以我们到了最后一个:
Given these definitions, a viable function
F1
is defined to be a better function than another viable functionF2
if for all argumentsi
, ICSi(F1
) is not a worse conversion sequence than ICSi(F2
), and then
— [...]
—F1
andF2
are function template specializations, and the function template forF1
is more specialized than the template forF2
according to the partial ordering rules described in 14.5.6.2.
规则是:
步骤 1:合成类型 [temp.func.order]:
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.
所以我们有:
void f(Pack1... args); // #1
void f(U2 a1, Pack2... args); // #2
步骤 2:按照 [temp.deduct.partial] 中的描述执行推导。我们所在的上下文是函数调用,因此我们使用函数调用具有参数的类型。
首先,我们尝试从#1 推导出#2。也就是说,我们尝试将 (T1, Args...
) 与 (Pack1...)
进行匹配。那么第一部分就是P = T1, A = Pack1...
。我们有:
If A was transformed from a function parameter pack and P is not a parameter pack, type deduction fails.
所以从#1 推导出#2 失败了,所以参数 Args...
至少不像 T1, Args...
那样专业。
接下来,我们尝试从#2 推导出#1。也就是说,我们尝试将 (Args...)
与 (U2, Pack2...)
进行匹配。成功了,所以 T1, Args...
至少和 Args...
.
由于#2 至少与#1 一样专业,而#1 至少不如#2 专业,我们可以说#2 更专业:
Function template
F
is at least as specialized as function templateG
if, for each pair of types used to determine the ordering, the type fromF
is at least as specialized as the type fromG
.F
is more specialized thanG
ifF
is at least as specialized asG
andG
is not at least as specialized asF
.
首选更专业的模板,因此我们调用#2。