In the code below, why does the first call to g resolve to the reference version, even though s is already an rvalue reference?
#include <string>
#include <iostream>
#include <utility>
void g(const std::string& s) {
std::cout << "g(const std::string&)\n";
}
void g(std::string&& s) {
std::cout << "g(std::string&&)\n";
}
void f(std::string&& s) {
static_assert(std::is_same<decltype(s), std::string&&>::value,
"s is not std::string&&");
static_assert(!std::is_same<decltype(s), std::string&>::value,
"s magically changed to std::string&");
g(s);
g(std::move(s));
}
int main() {
f("abc");
return 0;
}
Output:
g(const std::string&)
g(std::string&&)
As the static_asserts show, s hasn't magically started being treated as an lvalue reference in the body of the function, as I've seen some people assert (or maybe I misunderstood what they were saying).
(Note: After some investigation I think I've come up with a reasonable answer; but I'm completely not sure if it's accurate. So, I'd like to post my proposed answer and get comments on it. Sorry if this isn't the right way to ask whether my answer is correct - but ironically, meta.stackoverflow.com tells me I can't ask questions on asking questions until I've already asked some questions.)