#include <cstdio>
#include <functional>
template <class T>
class Property {
	T v;
public:
	Property(const Property&p) {*this=static_cast<T>(p);}
	//Property() { printf("ctor %X\n", this);}
	Property(){}
	Property& operator=(const Property& src) { return*this=static_cast<T>(src); }
	Property& operator=(const T& src) {
		printf("write %X\n", this);
		v = src; 
		return *this; 
	}
	operator T() const {
		printf("Read %X\n", this);
		return v;
	}
};

template <class T>
class Property2 {
	typedef T(*Gfn)();
	typedef void(*Sfn)(T);
	Gfn gfn;
	Sfn sfn;
public:
	Property2(const Property2&p) {*this=static_cast<T>(p);}
	//Property2() { printf("ctor %X\n", this);}
	Property2(Gfn gfn_, Sfn sfn_):gfn(gfn_), sfn(sfn_) {}
	Property2& operator=(const Property2& src) { return*this=static_cast<T>(src); }
	Property2& operator=(const T& src) {
		printf("write %X\n", this);
		sfn(src);
		return *this; 
	}
	operator T() const {
		printf("Read %X\n", this);
		return gfn();
	}
};

void set(int v) {}
int get() {return 9;}

Property<int> a, b;
Property2<int> c(get,set), d(get,set);
int main(){
	a=b=5;
	c=d=11;
	a=c=b=d=15;
}
