Just when I thought I was clear about c++ rvalue references, I came across this code:
class my_class {
public:
my_class() { }
auto set(const std::string& s)
{
std::cout << "set(const std::string&) - copying unmutable lvalue" << std::endl;
m_s = s;
}
auto set(std::string& s)
{
std::cout << "set(std::string& s) - copying mutable lvalue" << std::endl;
m_s = s;
}
auto set(std::string&& s)
{
std::cout << "set(std::string&& s) - moving mutable rvalue" << std::endl;
m_s = std::move(s);
}
auto set(const std::string&& s)
{
std::cout << "set(const std::string&& s) - moving unmutable rvalue" << std::endl;
m_s = std::move(s);
}
private:
std::string m_s;
};
int main()
{
my_class c;
std::string lvalue{"lvalue"};
const std::string const_lvalue{"const lvalue"};
std::cout << "1. c.set(lvalue)" << std::endl;
c.set(lvalue);
std::cout << "2. c.set(std::move(lvalue))" << std::endl;
c.set(std::move(lvalue));
std::cout << "3. c.set(const_lvalue)" << std::endl;
c.set(const_lvalue);
std::cout << "4. c.set(std::move(const_lvalue))" << std::endl;
c.set(std::move(const_lvalue));
std::cout << "5. c.set(std::string{\"rvalue\"})" << std::endl;
c.set(std::string{"rvalue"});
// compile error
// c.set(const std::string{"const rvalue"});
return 0;
}
Output:
1. c.set(lvalue)
set(std::string& s) - copying mutable lvalue
2. c.set(std::move(lvalue))
set(std::string&& s) - moving mutable rvalue
3. c.set(const_lvalue)
set(const std::string&) - copying unmutable lvalue
4. c.set(std::move(const_lvalue))
set(const std::string&& s) - moving unmutable rvalue
5. c.set(std::string{"rvalue"})
set(std::string&& s) - moving mutable rvalue
I don't understand 4. Why do we bind to a const rvalue reference and how does c++ allow to invoke std::move() on this thing?