我浏览了几个与此标题相同的主题,但找不到任何帮助我解决这个问题的内容......
以下是对“The C ++ Programming Language”,第二版,B Stroustrup,第13.3.2节(第336页)中的一个小例子的扫描。
我不明白第三个sqrt(z)
重载决议。我预计该决议将是sqrt<complex<double>>(complex<double>)
。
Obv函数double sqrt(double)
不适合账单。但我也认为template<class T>T sqrt(T)
无法解析为sqrt<double>(complex<double>)
,因为在我看来,暗示T
有两种不同的决议,我认为它们不能...... {{ 1}}在整个“范围”中必须是同一个东西。
我有什么东西被误解了,你能指出来吗? :)谢谢!
答案 0 :(得分:4)
第二个是适合呼叫的特殊化。参数是T,即
中的类型complex<T>
然后功能
sqrt<double>
请记住,编译器会选择最特殊的模板函数。
答案 1 :(得分:3)
在这种情况下,正如您所发现的,有两种方法可以将签名与模板匹配。第一个模板template<class T> T sqrt(T)
可以匹配。让T
等于complex<double>
会生成一个带有签名complex<double> sqrt(complex<double>)
的函数(模板特化)。
第二个模板template<class T> complex<T> sqrt(complex<T>)
也可以匹配。在这种情况下,将T
设置为double
会使用与第一个模板的特化相同的签名进行专门化。
模板重载决策选择更专业的模板:在这种情况下,仅适用于complex<T>
的模板。如果它有助于理解,您可以将T
重命名为第二个模板中的其他内容:模板如下:
template<class T> T sqrt(T);
template<class U> complex<U> sqrt(complex<U>);
这样,在两个函数模板中更容易看到模板参数不相关。您可以通过complex<double>
的适当选择或T
的适当选择获得U
,第二个模板更专业。