Intermediate Gotchas
The Rvalue Reference That Is an Lvalue
the parameter type is not the expression category
void inspect(const std::string&) { std::cout << "lvalue\n"; }
void inspect(std::string&&) { std::cout << "rvalue\n"; }
void send(std::string&& message) { inspect(message); }
int main() { send("hello"); }
Run it. Which overload sees message?
Why¶
message has type std::string&&, but every named variable expression is an lvalue. Overload
resolution therefore selects the const std::string& overload. This is not forwarding-reference
deduction; the same named-expression rule applies to every rvalue-reference parameter. GCC emits
no warning under -Wall -Wextra.
The fix¶
Cast only when this function is done with the object:
Takeaway: a named rvalue-reference parameter is an lvalue until you explicitly move it.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo