#include <iostream>
#include <utility>
#include <string>
using namespace std;
void foo(const string&) { cout << "const string&" << endl; }
void foo(string&&) { cout << "string&&" << endl; }
void bar(string&& x) { foo(x); }
// Use one of the following versions to get intended results
//void bar(string&& x) { foo(std::move(x)); }
//void bar(string&& x) { foo(std::forward<string>(x)); }
template<typename T>
void barbar(T&& x) { foo(std::forward<T>(x)); }
int main() {
cout << "» \"42\"" << endl;
foo("42"); // string&&
cout << "» const string a" << endl;
const string a = "Hello";
foo(a); // const string&
foo(std::move(a)); // const string& -> not string&& because a is const
cout << "» string b" << endl;
string b = "World";
foo(b); // const string&
foo(std::move(b)); // string&&
//bar(b); //cannot bind rvalue reference of type ‘string&&’ to lvalue of type ‘string’
bar(std::move(b)); // const string& -> why not string&& ?
cout << "» forwarding reference" << endl;
barbar(b); // const string&
barbar(std::move(b)); // string&&
return 0;
}