Search code examples
c++c++11functor

Make std::for_each more useful - is this a good idea for the functor to know the current index?


Often I cannot use std::for_each because my logic for a particular element depends on its current index. To that end, I've invented a functor class which wraps the main functor and passes it the current index. Ideally I want to use it with lambda expressions. Is the class I have created safe and effective? Are there any better solutions? I did want the wrapper's operator () to return the type of the lambda expression, but I couldn't figure that out. Also, what type should I use for the index? Should I store the main functor in the wrapper by value or reference?

Thanks!

template<class FUNC>
class IndexFunctor
{
public:
    typedef FUNC FUNC_T;

    explicit IndexFunctor(const FUNC_T& func) : func(func), index(0) {}

    // how can this return the return type of func?
    template<class T>
    void operator ()(T& param)
    {
        func(index++, param);
    }

    const FUNC_T& GetFunctor() const
    {
        return func;
    }

    int GetIndex() const
    {
        return index;
    }

    void SetIndex(int index)
    {
        this->index = index;
    }

private:
    FUNC_T func;
    int index;
};

template<class FUNC>
IndexFunctor<FUNC> with_index(const FUNC& func)
{
    return IndexFunctor<FUNC>(func);
}

void somefunc()
{
    std::vector<int> v(10);
    std::for_each(v.begin(), v.end(), with_index([](int index, int x){ std::cout << "[" << index << "]=" << x << std::endl; }));
}

Solution

  • That should be safe, although it's fairly straightforward to write an indexed for-each yourself.

    template <typename TInputIterator, typename TFunc>
    TFunc counted_for_each(TInputIterator first, TInputIterator last, TFunc func)
    {
        for (size_t i = 0; first != last; ++first)
        {
            func(i++, *first);
        }
    
        return func;
    }
    

    Less code and accomplishes the same thing.