#include <iostream>
#include <utility>

using namespace std;

struct foo {
	explicit foo(char const* s) : m_str(s) { cout << "init " << m_str << "\n"; }
	foo(foo const& other)  : m_str(other.m_str) { cout << "copy " << m_str << "\n"; }
	foo(foo&& other) : m_str(other.m_str) { cout << "move " << m_str << "\n"; }
	~foo() { cout << "destroy " << m_str << "\n"; }

	foo& operator = (foo const& other) { m_str = other.m_str; cout << "copy-assign " << m_str << "\n"; return *this; }
	foo& operator = (foo&& other) { m_str = other.m_str; cout << "move-assign " << m_str << "\n"; return *this; }

private:
	char const* m_str;
};

foo good() { return foo("good"); }
foo const bad() { return foo("bad"); }

void consume(foo) { }

template <class T> void consume2(T&& t) {
	consume(forward<T>(t));
}

int main()
{
	consume2(good());
	cout << "\n";
	consume2(bad());
//	cout << "\n";
//	good() = foo("nicht so gut");
}
