#include <vector>
#include <iostream>
#include <type_traits>

template<class ITERATORT,class ADAPTER>class IteratorAdapter : public ITERATORT {
    ADAPTER adapter_;
    public: IteratorAdapter(ITERATORT underlying,ADAPTER adapter) :
        ITERATORT(underlying),
        adapter_(adapter)
    {   }
    public: auto operator*(){
        return adapter_(ITERATORT::operator*());
    }
};
template<class COLLECTION,class ADAPTER>class CollectAdapter{
    using CollectAdapterT=CollectAdapter<COLLECTION,ADAPTER>;
    COLLECTION* collection_;    //<------ #1  problem?
    ADAPTER adapter_;
    public: CollectAdapter(COLLECTION& collection,ADAPTER adapter){
        collection_=&collection;
        adapter_=adapter;
    }
    public: auto begin(){
        return IteratorAdapter<
            decltype(std::declval<COLLECTION>().begin()),
            decltype(adapter_)>
            (collection_->begin(),adapter_);
    }
    public: auto end(){
        return IteratorAdapter<
            decltype(std::declval<COLLECTION>().end()),
            decltype(adapter_)>
            (collection_->end(),adapter_);
    }
};
class CollectAdapterWidget{
    public: template<class COLLECTION,class ADAPTER> static CollectAdapter<COLLECTION,ADAPTER> createAdapter(COLLECTION& collection,ADAPTER adapter){
        return CollectAdapter<COLLECTION,ADAPTER>(collection,adapter);
    }
};


int func1(int i){
    return i+10;
}
int func2(int i){
    return i+100;
}

int main(){
    std::vector<int> test;
    test.push_back(5);
    std::cout<<"start"<<std::endl;
    for(auto b:CollectAdapterWidget::createAdapter(test,func1)){
        std::cout<< b<<std::endl;
    }
    std::cout<<"end"<<std::endl;
}