1. Rvalue References
std::string returnStringByValue(); // forward declaration
...
std::string s{"hello"};
...
std::string&& r1{std::move(s)}; // OK
std::string&& r2{returnStringByValue()};
// OK, extends lifetime of return value
std::string&& r3{s}; // ERROR
①右值引用必须引用一个现存的对象,现存的对象必须作为初始值传递,
但是,根据移动语意的规则,它们只能引用一个没有名称的临时对象或标记为std::move()的对象
②std::string&& r3{s}; // ERROR
③没有名称的临时对象和被move标记的对象,我们称之为右值
这些对象只能引用 右值
2. 如何初始化右值引用
std::string s{"hello"};
...
std::string&& r1{std::move(s)}; // OK, reference to s
std::string&& r2 = std::move(s); // OK, reference to s
std::string&& r3(std::move(s)); // OK, reference to s
3.右值引用作为形参
①这个形参 只能被临时对象或者被move标记的对象绑定
②你可以随意修改这个对象
③调用该函数的人,表示该对象的值已经没用了,但是该对象还是可以使用
④任何修改都应该保持被引用的对象处于有用的状态
void foo(std::string&& rv);
// takes only objects where we no longer need the value
...
std::string s{"hello"};
...
foo(s); // ERROR
foo(std::move(s)); // OK, value of s might change
foo(returnStringByValue()); // OK
⑤一个对象std::move(),作为实参被传入以后,就不该在被使用了
该对象仍是可以使用的
void foo(std::string&& rv);
// takes only objects where we no longer need the value
...
std::string s{"hello"};
...
foo(std::move(s)); // OK, value of s might change
std::cout << s << \n;
// OOPS, you don’t know which value is printed
foo(std::move(s)); // OOPS, you don’t know which value is passed
s = "hello again"; // OK, but rarely done
foo(std::move(s)); // OK, value of s might change