在C++中解析函数参数/参数

问题描述:

我目前正在通过'Effective Modern C++'来更新我对该语言的了解,并刚刚完成了第27项,该项处理重载函数,它将转发(或通用本书称他们)参考。使用下面的代码,我写道:在C++中解析函数参数/参数

#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是一个右值,因此模板应该实例为“无效FUNC(INT & & PARAM)”和呼叫应该是转发版本?很明显,这是我的理解显然是缺乏的,但澄清这一点会有所帮助。我了解标准在相同功能签名的情况下表示,应该优先使用非模板函数,但是(至少在我看来)这不适用于此?非常感谢。

问候, 菲尔

+0

注意'func(int &&)'不比'func(int)'更好匹配。如果您将这两个视为非模板,则该呼叫不明确。 – aschepler

+0

因为肯定模板匹配void func(int && param)会比void func(int param)更好 - 它们不一样。还是我只是一个白痴?完全有可能我承认:-) – PhilPotter1987

+0

@aschepler:啊,我明白了,那是我缺乏理解的地方。我认为他们会不同并且可以重载 - 实际上没有尝试过。请张贴作为答案,我会高兴地接受。 – PhilPotter1987

呼叫func(29)功能void func(int)匹配,无需转换。这被称为身份转换超载分辨率,这是在排名类别完全匹配

最佳可行函数的排名规则在[over.match.best]中指定函数在重载解析期间何时比其他函数更好匹配。

根据[over.ics.rank],身份转换绝不是比任何其他转换序列更糟的转换序列,所以void func(int)永远不会在前5条规则下被打败。第6条是:

F1被定义为比另一种可行的功能 F2更好的功能,如果对所有的参数

[...]

F1不是一个函数模板特殊化和F2是一个功能模板专业化,[...]

因此,非模板标识转换总是胜过任何模板实例化。