#include <iostream>

struct A {
	struct APlusA {
		APlusA(const A&a_, const A&b_) : a(a_), b(b_) {}
		const A &a;
		const A &b;
		
		operator A() const { 
			std::cout << "Creating temporary A" << std::endl; 
			return A(a.val + b.val);
		}
	};

	A(int val_) : val(val_) {}
	friend APlusA operator+(const A&a, const A&b) { return APlusA(a,b); }
	friend std::ostream &operator<<(std::ostream &s, const A &a) { return s << a.val;}
	
	A& operator=(const APlusA &apa) {
		if (this == &apa.a) {
			std::cout << "Performing in-place operator" << std::endl;
			val += apa.b.val;
		}
		else
		{
			*this = static_cast<A>(apa);
		}
	}
	
	int val;
};

int main() {
	A a(4), b(5), c(6);
	std::cout << a+b << std::endl; //Temporary created
	a = b+c;                       //Temporary created
	a = a+b;                       //No temporary - inplace operation
	std::cout << a << std::endl;
	return 0;
}
