#include <iostream>

template <typename T, typename V>
class Property
{
public:
  typedef V (T::*getter_type)() const;
  typedef void (T::*setter_type)(const V &value);
  Property(T *self, getter_type getter, setter_type setter) : self_(self), getter_(getter), setter_(setter) {}
  V get() const { return (self_->*getter_)(); }
  Property &set(const V &v) { (self_->*setter_)(v); return *this; }
  operator V() const { return get(); }
  Property &operator=(const V &v) { return set(v); }
  Property &operator+=(const V &v) { return set(get() += v); }
private:
  T *self_;
  getter_type getter_;
  setter_type setter_;
};

struct Integer
{
  int value_;
  Integer(const int value) : value_(value) {}
  operator int() const { return value_; }
  Integer &operator =(const int value) { value_ = value; return *this; }
  Integer &operator +=(const int value) { value_ += value; return *this; }
  friend std::ostream &operator<<(std::ostream &os, const Integer &i) { os << i.value_; return os; }
};

class Hoge
{
public:
  Hoge() : foo(this, &Hoge::get_foo, &Hoge::set_foo), foo_(0xdeadbeef) {}
  Property<Hoge, Integer> foo;
  Integer get_foo() const { return foo_; }
  void set_foo(const Integer &v) { foo_ = v; }
private:
  Integer foo_;
};

int main()
{
  Hoge hoge;
  (hoge.foo = 123) += 456;
  std::cout << hoge.foo << std::endl;
  return 0;
}
