[英]Overload resolution with templates and rvalue references
这种重载解析行为让我感到困惑:
#include "stdio.h"
template<class T>
class C
{
public:
C(T v): m(v) {};
T m;
template<class U>
T f(U &&p)
{
printf("rRef called.\n");
return p;
}
template<class U>
T f(const U &p)
{
printf("const Ref called.\n");
return p;
}
};
int main()
{
C<int> a(5);
a.f<int&>(a.m);
a.f(a.m);
return 0;
}
输出:
const Ref called.
rRef called.
在 gdb 或 Visual Studio 中调试时,两个调试器都显示int C<int>::f<int &>()
在两种情况下调用,但显式模板解析解析为预期的 const ref,而第二个解析为右值引用. 为什么? 为什么编译器甚至不尝试我认为是明显匹配的int C<int>::f<int>()
? 右值引用如何绑定到成员值? 是不是am
一个左值?
当您拨打电话时:
a.f<int&>(a.m);
编译器必须在以下候选者之间进行选择:
template<class U>
T f(U && p); // #1
template<class U>
T f(U const & p); // #2
对于这个重载解析过程,首先为参数int&
转换两个模板。
用U = int &
替换#1
得到int & &&
,由于引用折叠,它变成了int &
。
类似地,将U = int &
替换为#2
得到int & const &
,这又是由于引用折叠,变成了int &
。
现在,由于两个重载匹配,因此使用偏序来确定要调用的模板。 现在U const &
比U &&
更专业。 这是因为U &&
可以绑定到U const &
可以绑定的所有类型,但反之则不然。
因此,由于#2
更专业,它在重载决议中获胜,并被调用。
在这次通话中:
a.f(a.m);
未指定模板参数。 这意味着#1
的参数被认为是一个转发引用,它匹配传入的所有类型,因此#1
被调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.