#include <iostream>
#include <string>
std::string m_str;
void a(std::string&& other)
{
m_str = std::string(other); // this is wrong
std::cout << "a: " << other << std::endl;
// other is not EMPTY because inside the function,
// the argument "other" got a name, and lost it's "rvalueness"
}
void b(std::string&& other)
{
m_str = std::string(std::move(other));
std::cout << "b: " << other << std::endl;
// other is empty because std::move converted the lvalue "other" back to "rvalue"
}
void c(std::string&& other)
{
m_str = std::string(std::forward<std::string>(other)); // other is empty as well.
// because this function only accepts RValues, so std::forward does the same as std::move
// if you call this function with a lvalue, you will get compile error.
std::cout << "c: " << other << std::endl;
}
//This functions accepts both rvalues and lvalues (other is a "forwarding reference")
template<typename T>
void d(T&& other)
{
m_str = std::string(std::forward<T>(other)); //If you use move here, other will always be empty.
std::cout << "d: " << other << std::endl;
// If other was an rvalue, other will be empty.
// If other was an lvalue, other will NOT be empty.
}
int main()
{
a(std::string("Hello World"));
b(std::string("Hello World"));
c(std::string("Hello World"));
d(std::string("Hello World"));
std::string lvalue = "Hello World";
d(lvalue);
return 0;
}