#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
#include <iterator>

struct Foo
{
   int value;
   Foo(int value) : value(value){};
};

struct Bar
{
    std::vector<Foo> values;
    size_t size_foo() const {return values.size();}
    Foo& get_foo(size_t index) {return values[index];}
};

template <typename TOuter, typename TInner> struct ContainerProxy;

template <typename TOuter, typename TInner>
struct ContainerIterator : public std::iterator<std::input_iterator_tag, TInner>
{
    typedef std::function<TInner& (TOuter*, size_t)> getfunc_type;
    TOuter& mContainerRef;
    size_t mIndex;
    getfunc_type mGetfunc;

    ContainerIterator(TOuter& containerRef, size_t index, getfunc_type const& getFunc)
	: mContainerRef(containerRef), mIndex(index), mGetfunc(getFunc)
    {
    }

    TInner& operator*() {return mGetfunc(&mContainerRef, mIndex);}
    ContainerIterator<TOuter, TInner>& operator++() {++mIndex; return *this;}

    bool operator==(ContainerIterator<TOuter, TInner> const& rhs) const
    {
        return &mContainerRef==&rhs.mContainerRef &&
               mIndex==rhs.mIndex;
    }

    bool operator!=(ContainerIterator<TOuter, TInner> const& rhs) const
    {
        return !operator==(rhs);
    }
};

template <typename TOuter, typename TInner>
struct ContainerProxy
{
    TOuter& mContainerRef;

    typedef std::function<size_t (TOuter*)> sizefunc_type;
    sizefunc_type mSizefunc;

    typedef std::function<TInner& (TOuter*, size_t)> getfunc_type;
    getfunc_type mGetfunc;


    ContainerProxy(TOuter& containerRef, sizefunc_type sizefunc, getfunc_type getfunc) :
        mContainerRef(containerRef), mSizefunc(sizefunc), mGetfunc(getfunc)
    {
    }

    ContainerIterator<TOuter, TInner> begin() const
    {
        return ContainerIterator<TOuter, TInner>(mContainerRef, 0, mGetfunc);
    }

    ContainerIterator<TOuter, TInner> end() const
    {
        return ContainerIterator<TOuter, TInner>(mContainerRef, mSizefunc(&mContainerRef), mGetfunc);
    }
};


int main()
{
    Bar b;
    b.values.push_back(Foo(1));
    b.values.push_back(Foo(2));

    ContainerProxy<Bar, Foo> proxy(b, &Bar::size_foo, &Bar::get_foo);

    std::for_each(proxy.begin(), proxy.end(), [](Foo& f) {std::cout<<f.value<<std::endl;});
}