#include <iostream>
#include <iterator>

struct Foo;

template<typename Type>
struct MemberPtrBase {
    virtual ~MemberPtrBase() { }

	virtual Type get() const = 0;
	virtual MemberPtrBase & set(Type const &) = 0;
};

template<typename Class, typename RealType, typename CommonType>
struct MemberPtr : MemberPtrBase<CommonType> {
public:
	MemberPtr(Class * object, RealType(Class::*member))
	: m_object(object), m_ptr(member)
	{ }

	CommonType get() const {
		return m_object->*m_ptr;
	}

	MemberPtr & set(CommonType const & val) {
		m_object->*m_ptr = val;
		return *this;
	}

	MemberPtr & operator=(RealType const & val) {
		return set(val);
	}

	operator CommonType() const {
		return get();
	}
private:
	Class * m_object;
	RealType (Class::*m_ptr);
};

template<typename Class, typename... Types>
struct MemberIterator {
public:
	using CommonType = typename std::common_type<Types...>::type;
public:
	MemberIterator(Class & obj, std::size_t idx, Types(Class::*...member))
	: m_object(obj), m_index(idx), m_members { new MemberPtr<Class, Types, CommonType>(&obj, member)... }
	{ }

	MemberPtrBase<CommonType> & operator*() const {
		return *m_members[m_index];
	}

	bool operator==(MemberIterator const & it) const {
		return (&m_object == &it.m_object) && (m_index == it.m_index);
	}

	bool operator!=(MemberIterator const & it) const {
		return (&m_object != &it.m_object) || (m_index != it.m_index);
	}

	MemberIterator & operator++() {
		++m_index;
		return *this;
	}
private:
	Class & m_object;
	std::size_t m_index;
	MemberPtrBase<CommonType> * m_members[sizeof...(Types)];
};

struct Foo {
public:
	using iterator = MemberIterator<Foo, int, int, int, int>;
public:
	Foo(int a, int b, int c, int d)
	: m_a(a), m_b(b), m_c(c), m_d(d)
	{ }

	iterator begin() {
		return iterator(*this, 0, &Foo::m_b, &Foo::m_d, &Foo::m_c, &Foo::m_a);
	}

	iterator end() {
		return iterator(*this, 4, &Foo::m_b, &Foo::m_d, &Foo::m_c, &Foo::m_a);
	}
private:
	int m_a, m_b, m_c, m_d;
};

int main(int argc, char ** argv) {
	Foo foo { 1, 2, 3, 4 };

	for(auto & mem : foo) {
		std::cout << mem.get() << std::endl;
		mem.set(3);
	}

	for(auto & mem : foo) {
		std::cout << mem.get() << std::endl;
	}
}