我目前正在努力学习“Effective Modern 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 是一个右值,因此模板应该实例化为“void func(int&& param)”并且调用应该是转发版本?显然它就是这样,所以我的理解显然是缺乏的,但对这一点的澄清会有所帮助。我知道标准说在相同函数签名的情况下,应该首选非模板函数,但是(至少在我看来)这在这里不适用吗?非常感谢。
问候, 菲尔
最佳答案
调用 func(29)
与函数 void func(int)
匹配,无需转换。这称为用于重载解析的身份转换,属于完全匹配排名类别。
[over.match.best] 中最佳可行函数的排名规则指定函数在重载解析期间何时比其他函数更匹配。
根据 [over.ics.rank],身份转换永远不会比任何其他转换序列更差,因此 void func(int)
永远不会在前 5 条规则下被打败.规则 6 是:
F1 is defined to be a better function than another viable function F2 if for all arguments
[...]
F1 is not a function template specialization and F2 is a function template specialization, [...]
因此非模板身份转换总是胜过任何模板实例化。
关于c++ - C++ 中函数参数/参数的解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43645582/