#include <iostream>
 
struct A
{
	int val;
 
	A(int val) : val(val) { std::cout << "A(int) val = " << val << '\n'; }
 
	A(const A& other) : val(other.val) { std::cout << "A(const A&) val = " << val << '\n'; }
	A(A&& other) : val(other.val) { other.val = 0; std::cout << "A(A&&) val = " << val << '\n'; }
 
	~A() { std::cout << "~A() val = " << val << '\n'; }
 
	A& operator = (const A& rhs) { val = rhs.val; std::cout << "A& operator = (const A&) val = " << val << '\n'; return *this; }
	A& operator = (A&& rhs) { val = rhs.val; rhs.val = 0; std::cout << "A& operator = (A&&) val = " << val << '\n'; return *this; }
};
 
A foo()
{
	A a(77);
	return a;
}
 
A bar()
{
	A a(777);
	return std::move(a);
}
 
int main()
{
	{
		std::cout << "foo:\n";
		A a = foo();
	}
	{
		std::cout << "bar:\n";
		A v = bar();
	}
}