First, constant rvalue reference are not really useful, since you cannot move them. Moving value need mutable references to work.
Let's take your corrected example:
void write_lvalue(std::string const& text) {
//...
}
void write_rvalue(std::string&& text) {
//...
}
int main() {
write_lvalue("writing the Lvalue");
write_rvalue("writing the Rvalue");
}
In this case, the two are completely equivalent. In these two case, the compiler has to create a string and send it by reference:
int main() {
// equivalent, string created
// and sent by reference (const& bind to temporaries)
write_lvalue(std::string{"writing the Lvalue"});
// equivalent, string created
// and sent by reference (&& bind to temporaries)
write_rvalue(std::string{"writing the Rvalue"});
}
So why have function that takes rvalue references?
It depends on what you do with the string. A mutable reference can be moved from:
std::string global_string;
void write_lvalue(std::string const& text) {
// copy, might cause allocation
global_string = text;
}
void write_rvalue(std::string&& text) {
// move, no allocation, yay!
global_string = std::move(text);
}
So why using rvalue reference at all? Why not using mutable lvalue reference?
That is because mutable lvalue references cannot be bound to temporaries:
void write_lvalue_mut(std::string& text) {
// move, no allocation... yay?
global_string = std::move(text);
}
int main() {
std::string s = /* ... */;
write_lvalue_mut(std::move(s)); // fails
write_lvalue_mut("some text"); // also fails
}
But mutable rvalue reference can be bound to rvalue, as shown above.
const std::string &&text
should not be used. You defeat the purpose of the rvalue reference by making what it refers toconst
. If it isconst
it can't be moved from as that is a mutating operation. – Brandeebranden