C++ 中函数 arguments/parameters 的解析

Resolution of function arguments/parameters in C++

我目前正在努力完成 '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) 匹配,无需转换。这被称为 身份转换 用于重载解析,属于排名类别 Exact Match.

[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, [...]

所以非模板身份转换总是胜过任何模板实例化。