« Earlier3 items total Later »

C++ foreach idiom

Isn't the STL wonderfull .... until you have started using languages such as Python and Ruby. In C++ to iterate over a STL container you have to write ick like this.


vector<int> v;
//Put some stuff in v

vector<int>::iterator it = v.begin();
for (;it != it.end(); it++ ){
   cout << *it;
}


Now I say that is clunky. STL iterator syntax is great when you want to do complex things but nasty when you want to do simple things. Have a look at this code which does exactly the same as the above code.


vector<int> v;
//Put some stuff in v

for(each<int> it; it.in(v);){
   cout << *it;
}


Much nicer. And here is the implementation of each. Obviously to achieve this magic you have some performance penalty as I need to take advantage of a class with virtual functions. Anybody who can see a way to improve this please contact me.


template <typename T> class iter{
public:
    virtual void inc() = 0;
    virtual T & operator*() = 0;
    virtual bool end() = 0;
    virtual ~iter() {

    }
};

template <typename T> class each{

    iter<T> * mIter;
    bool mIsEnd;
    T * mCurrent;

public:

    template <class C> class iterImpl : public iter<T> {
        typename C::iterator mIt;
        typename C::iterator mEnd;
    public:

        iterImpl(C & c):mIt(c.begin()), mEnd(c.end()){

        }
        void inc(){
            ++mIt;
        }
        T & operator*(){
            return *mIt;
        }
        bool end(){
            return mIt == mEnd;
        }
    };


    each(): mIter(NULL),mIsEnd(false),mCurrent(NULL)
    {
    }

    T & operator*(){
        return *mCurrent;
    }

    template <class C>bool in(C & container){
        if (mIter==NULL){
            mIter = new iterImpl<C>(container);
        }
        mCurrent = &**mIter;
        mIter->inc();
        if (mIsEnd){
            return false;
        }
        mIsEnd = (mIter->end());
        return true;
    }

};


Perform an operation on each item of an array and collect the results

>> a = { 'cow' 'cat' 'dog' };
>> collect(a, @(x)fliplr(x))

ans =

    'woc'    'tac'    'god'


Implementation
function out = collect(arr, fh)
    out = cell(size(arr));
    for i = 1:length(arr)
        if iscell(arr)
            out{i} = fh(arr{i});
        else
            out{i} = fh(arr(i));
        end
    end
end

Perform an operation on each item of an array

>> a = { 'cow' 'cat' 'dog' };
>> each(a, @(x)disp(fliplr(x)))
woc
tac
god
>>


Implementation for each.m
function each(arr, fh)
    for i=1:length(arr)
        if iscell(arr)
            fh(arr{i});
        else
            fh(arr(i));
        end
    end
end

« Earlier3 items total Later »




Sponsored by

Sole Central

Your one stop shop for Birkenstock and Crocs shoes and sandles.