c++ - C++ 中函数参数/参数的解析

标签 c++ templates rvalue perfect-forwarding

我目前正在努力学习“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/

相关文章:

c++ - 如何在 CMake 中设置此文件夹结构?

c++ - 更改构造函数优先级

c++ - 在 C++ 中,我可以使用定义中未使用的模板参数来声明模板结构吗?

无法在 Visual Studio 2012 中编译但在 Visual Studio 2005 中运行良好的 C++ 类型转换运算符代码

c++ - 在 C++ 中紧凑地保存霍夫曼树

c++ - QT 线程:获取 QObject::startTimer:定时器不能从另一个线程警告启动

C++ 访问继承类的成员,其中继承类是模板参数

c++ - 具有新放置的右值引用(与 std::vector.push_back 类似的功能)

C++ 非常量-常量引用函数重载

c++ - [C++][SFML 2.2] 奇怪的性能问题 - 移动鼠标会降低 CPU 使用率