我目前正在通过'有效的现代C ++'来更新我对该语言的了解,并刚刚完成了第27项,它处理了转载(或书籍称之为通用)引用的重载函数。使用以下代码我写道:
#include <iostream>
template <typename T>
void func(T&& param) {
std::cout << "forwarding reference version\n";
}
void func(int param) {
std::cout << "int version\n";
}
int main() {
func(29);
}
请有人解释为什么调用int版本,即使29是rvalue,因此模板应该实例化为“void func(int&amp;&amp; param)”并且调用应该是转发版本?显然它就是它,所以我的理解显然缺乏,但澄清这一点会有所帮助。我理解标准说在相同功能签名的情况下,应该首选非模板化函数,但(至少在我看来)这不适用于此?非常感谢。
此致 菲尔
答案 0 :(得分:5)
致电func(29)
与功能void func(int)
匹配,无需转换。这称为重载解析的身份转换,位于排名类别完全匹配。
[over.match.best]中最佳可行功能的排名规则指定在重载解析期间函数何时比其他函数更好匹配。
根据[over.ics.rank],身份转换从来不是比任何其他转换序列更差的转换序列,因此void func(int)
永远不会在前5条规则下被打败。规则6是:
F1被定义为比另一个可行功能更好的功能 如果适用于所有参数,则为F2
[...]
F1不是函数模板特化,F2是函数模板特化,[...]
因此,非模板标识转换总是胜过任何模板实例化。