jac*_*k X 4 c++ partial-ordering language-lawyer function-templates template-argument-deduction
template <typename T>
void show(T&); // #1
template <typename T>
void show(T const&); // #2
int main()
{
int a = 0;
show(a); // #1 to be called
}
Run Code Online (Sandbox Code Playgroud)
我对这些偏序规则感到困惑。以下是一些引用:[temp.deduct.partial]/5
在完成偏序之前,对用于偏序的类型执行某些转换:
如果
P
是引用类型,P
则替换为引用的类型。如果
A
是引用类型,A
则替换为引用的类型。
如果
P
和A
都是引用类型(在被上面提到的类型替换之前),确定这两种类型中的哪一种(如果有的话)比另一个更符合 cv 限定;否则,出于偏序目的,这些类型被视为同样具有 cv 限定。下面将使用该确定的结果。
删除任何顶级 cv 限定符:
如果
P
是 cv 限定类型,P
则替换为 的 cv 非限定版本P
。如果
A
是 cv 限定类型,A
则替换为 的 cv 非限定版本A
。
首先,void show(T&)
和void show(T const&)
都可以通过传递一个int
左值来调用,所以我们需要使用偏序规则来决定哪个函数更匹配。然后,根据上面的引用,我们做一些转换。第1步:
template <typename T>
void show(T&); // #1
template <typename T>
void show(T const&); // #2
int main()
{
int a = 0;
show(a); // #1 to be called
}
Run Code Online (Sandbox Code Playgroud)
第2步:
T& => T #3
T const& => T const #4
Run Code Online (Sandbox Code Playgroud)
#5 => #6
, #6 => #5
, 两个方向的推导都成功。然后以下规则起作用:[temp.deduct.partial]/9
如果,对于给定类型,扣除在两个方向成功(即,类型是上述变换后相同的)和二者
P
并A
分别引用类型(被替换为类型提及的上述前):
如果参数模板中的类型是左值引用而参数模板中的类型不是,则认为参数类型至少不像参数类型那样特殊;
否则,如果参数模板中的类型比参数模板中的类型更具有 cv 限定(如上所述),则认为参数类型至少不会像参数类型那样专门化。
所以#4
更专业呢#3
。对于给定的值a
,#2
应该调用#1
函数,但实际上调用的是函数。为什么?我的理解有问题吗?
在这种情况下,不使用“更专业”的规则,这是一个决胜局,以防对隐式转换序列进行排名并不能确定函数的顺序:[over.match.best]/1
ICS i (F) 定义如下:
[...]
鉴于这些定义,如果对于所有参数i,ICS i (F1) 不是比 ICS i (F2)更差的转换序列,那么一个可行函数 F1 被定义为比另一个可行函数 F2 更好的函数 ,然后
在这种情况下,仅对隐式转换序列进行排名就足以确定顺序,因此“或,如果不是”之后的所有内容都将被忽略。推导导致(int&)
#1 和(int const&)
#2,因此在这两种情况下,引用绑定(a
toint&
和a
to int const&
)都会导致身份转换,而不管 cv 限定:[over.ics.ref]/1
当引用类型的参数直接绑定到参数表达式时,隐式转换序列是恒等转换,除非参数表达式的类型是参数类型的派生类,在这种情况下,隐式转换序列是派生的 -到基础转换([over.best.ics])。[...]
但是,由于[over.ics.rank]/3,ICS1(#1) 是比 ICS1(#2) 更好的转换序列:
两个相同形式的隐式转换序列是不可区分的转换序列,除非以下规则之一适用:
因此,ICS1(F1) 是比 ICS1(F2) 更好的转换序列,因此根据[over.match.best]/(1.3)(以上),F1 优于 F2 。的[over.match.best] /(1.7)规则不被使用。
“更专业”的规则用于相反的情况:
int const a = 0;
show(a); // #2 should be called for a const lvalue
Run Code Online (Sandbox Code Playgroud)
这一次,推导结果为int const&
and int const&
,因此[over.match.best]/(1.7)开始。结果,正如您所观察到的,#2 是一个比 #1 更好的函数。
(强调我的,所有报价)
归档时间: |
|
查看次数: |
110 次 |
最近记录: |