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<int>::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<int>::f<int>() which I thought would be the obvious match? How can a rvalue reference bind to a member value? Isn't a.m a lvalue?
U &&is not an rvalue reference, but a forwarding reference in this instance, which can bind to anything. I'm more surprised bya.f<int&>(a.m)calling the const-ref version.