vendredi 16 octobre 2020

C++ overload resolution with templates

This overload resolution behavior baffles me:

#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;
}

Outputs:

const Ref called.
rRef called.

When debugging in gdb or Visual Studio, both debuggers show int C::f<int &>() called in both cases, but the explicit template resolution resolves to the expected const ref, while the second resolves to a rvalue reference. Why? Why doesn't the compiler even try int C::f() which I thought would be the obvious match? How can a rvalue reference bind to a member value? Isn't a.m a lvalue?

Aucun commentaire:

Enregistrer un commentaire