C++ 为什么模板重载比简单转换更匹配?
在其他情况下,当重载解析可能不明确时,首选非模板函数,为什么这一个不同?我认为(但不是绝对确定,即不知道标准中的确切引用,尽管会尝试查找),如果参数与非模板的类型不完全匹配,然后模板将生效。或者,换句话说,转换的数量趋于最小化。例如,在C++ 为什么模板重载比简单转换更匹配?,c++,templates,overload-resolution,C++,Templates,Overload Resolution,在其他情况下,当重载解析可能不明确时,首选非模板函数,为什么这一个不同?我认为(但不是绝对确定,即不知道标准中的确切引用,尽管会尝试查找),如果参数与非模板的类型不完全匹配,然后模板将生效。或者,换句话说,转换的数量趋于最小化。例如,在 matched template vs 模板 f(T) f(long)需要转换(从0,例如int,到long),而模板不需要转换(当然) 经过@T.C.的挖掘和帮助,本标准的相关部分为第。13.3.3[超过。匹配。最佳]。这是一个相当长的技术部分,但基本上说
matched template
vs
模板
f(T)
f(long)
需要转换(从0
,例如int
,到long
),而模板不需要转换(当然)
经过@T.C.的挖掘和帮助,本标准的相关部分为第。13.3.3[超过。匹配。最佳]。这是一个相当长的技术部分,但基本上说,具有
标识
转换的函数优于非标识
转换。隐式转换可能会带来开销,并且可能会出乎程序员的意料,因此,在我看来,标准选择不涉及转换的选项似乎是合乎逻辑的。§13.3.3[over.match.best]/p1-2:
1定义ICSi(F),如下所示:
- (1.1)[省略不适用的项目符号]
- (1.2)让
表示将列表中的第i个参数转换为 可行功能ICSi(F)
。13.3.3.1定义了隐式转换 序列和13.3.3.2定义了它对一个隐式 转换序列是更好的转换序列还是更差的转换序列 转换顺序不同F
F1
被定义为
比另一个可行函数更好的函数F2
if用于所有参数
i
,ICSi(F1)
的转换顺序并不比ICSi(F2)
差,
然后
- (1.3)对于某些参数
,j
是比ICSj(F1)
更好的转换顺序,或者,如果不是这样ICSj(F2)
- [省略了几个不适用的项目符号]
- (1.6)
不是函数模板专门化,而F1
是函数模板专门化,如果不是F2
- [不适用的项目符号省略]
- (3.2)如果
- (3.2.1)
是S1
的适当子序列(比较13.3.3.1.1中定义的标准形式的转换序列,不包括任何 左值变换;考虑身份转换序列 是任何非身份转换序列的子序列)S2
- (3.2.1)
设F1=
func(int)
,F2=func(long)
,只有一个参数,类型为int
。所以ICS1(F1)
是身份转换ICS1(F2)
是从int
到long
的整数转换;因此,ICS1(F1)
是比ICS1(F2)
per[over.ics.rank]/3.2.1更好的转换顺序(因此根据定义并不比ICS1(F2)
)。因此,根据[over.match.best]中的1.3号项目符号,F1优于F2。bullet 1.6中的模板/非模板平局破坏者根本无法发挥作用。0
是一个int
,而不是长
。模板函数可以提供分辨率,而无需进行转换。我猜:)FWIW,我最近又看了一遍,忘了它有多好。这是在问为什么规则是这样的,还是仅仅是来自标准的信息来说明规则?“当重载解析可能不明确时,非模板函数是首选的”-当然。但是在void f(int)中没有什么不明确的地方;空隙f(长);f(0)
@NeilKirk这两个都很好:)模板参数演绎发生,你最终得到(模板)f(int)
vs.f(long)
。当(template)f(int)
与f(int)
@chris之间存在歧义时,模板是不需要的,你最终会得到f(0)
被推断为f(int)
,然后是f(long)
的另一个重载。现在,f(int)
是一个更好的匹配,因为0
是一个int
文本,但需要对long
进行转换。是的,只是让找到相关标准更容易一些。从[over.match.best]开始。这项工作获得了高票!此时,我真的无法解析所有的standardese:)
matched template
f(long)
template <typename T>
f(T)