#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;
}