String address 0x7ffc833f4660 in main B, str test
String address 0x7ffc833f4660 in main C, str test
String address 0x7ffc833f4680 in funcc, str test
String address 0x7ffc833f4660 in main D, str
String address 0x7ffc833f4680 in main E, stra testa
String address 0x7ffc833f4680 in funcd A, str testa
String address 0x7ffc833f4680 in funcd B, str , strs testa
String address 0x7ffc833f4680 in main F, stra
funca 函数接收右值引用作为参数,由 funca 函数内部及函数调用前后的输出可以看到, std::move() 本身什么都没做,单单调用 std::move() 并不会将原来的对象的内容移动到任何地方。 std::move() 只是一个简单的强制类型转换,将左值转为右值引用。同时可以看到,用右值引用作为参数构造对象,也并没有对右值引用所引用的对象产生任何影响。
funcb 函数接收左值引用作为参数,上面的代码中,如下这一行注释掉了:
// funcb(std::move(str));
这是因为, funcb 不能用一个右值引用作为参数来调用。用右值引用作为参数,调用接收左值引用作为参数的函数 funcb 时,会编译失败:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/DemoTest.d" -MT"src/DemoTest.o" -o "src/DemoTest.o" "../src/DemoTest.cpp"
../src/DemoTest.cpp: In function ‘int main()':
../src/DemoTest.cpp:34:18: error: cannot bind non-const lvalue reference of type ‘std::__cxx11::string& {aka std::__cxx11::basic_string<char>&}' to an rvalue of type ‘std::remove_reference<std::__cxx11::basic_string<char>&>::type {aka std::__cxx11::basic_string<char>}'
funcb(std::move(str));
~~~~~~~~~^~~~~
../src/DemoTest.cpp:17:6: note: initializing argument 1 of ‘void funcb(std::__cxx11::string&)'
void funcb(std::string &str) {
^~~~~
src/subdir.mk:18: recipe for target 'src/DemoTest.o' failed
make: *** [src/DemoTest.o] Error 1
不过,如果 funcb 接收 const 左值引用作为参数,如 void funcb(const std::string &str) ,则在调用该函数时,可以用右值引用作为参数,此时 funcb 的行为与 funca 基本相同。
funcc 函数接收左值作为参数,由 funcc 函数内部及函数调用前后的输出可以看到,由于有了左值作为接收者,传入的右值引用所引用的对象的值被 move 走,进入函数的参数栈对象中了。
funcd 函数与 funca 函数一样,接收右值引用作为参数,但 funcd 的特别之处在于,在函数内部,右值构造了一个新的对象,因而右值引用原来引用的对象的值被 move 走,进入了新构造的对象中。










