#include <iostream>
class Foo { };
Foo createFoo() { return Foo(); }
void bar(Foo &&) { std::cout << "in bar(Foo &&)\n"; }
void bar(Foo const &) { std::cout << "in bar(Foo const &)\n"; }
void baz(Foo &&f) {
std::cout << "in baz, ";
bar(f);
// bar(std::move(f));
}
int main()
{
baz(createFoo());
return 0;
}
My expected output is: in baz, in bar(Foo &&)
, but I'm getting: in baz, in bar(Foo const &)
. If I switch the calls to bar
(see the comment) I get the expected output, but this seems wrong to me. Is there some reason the compiler can't call bar(Foo &&)
without me converting a Foo&&
to a Foo&&
?
Thanks in advance!
Inside baz(Foo&& f)
, f
is an lvalue. Therefore, to pass it on to bar
as an rvalue reference you have to cast it to an rvalue. You can do this with a static_cast<Foo&&>(f)
, or with std::move(f)
.
This is to avoid accidentally moving things multiple times in the same function e.g. with multiple calls to bar(f)
inside baz
.
In short, the rule is that a named rvalue reference is an lvalue. This is to prevent automatically moving out of a named variable that you then need to use later. In contrast unnamed temporaries can never be used again and so can be automatically moved from.
I found this series http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ to be pretty helpful even though it's a little bit old.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With