繁体   English   中英

使用模板和右值引用重载解析

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM