Using for_each with a vector of vectors

Discussion in 'C++' started by PolkaHead, Nov 28, 2006.

  1. PolkaHead

    PolkaHead Guest

    I was wondering if there's a way to traverse a two-dimensional vector
    (vector of vectors) with a nested for_each call.

    The code included traverses the "outer" vector with a for_each, than it
    relies on the PrintFunctor to traverse the "inner" vector with another
    for_each. Is it possible to nest the second for_each, so I don't have
    to include a for_each in my function object.

    Is it possible to do a:
    for_each(myVec.begin(), myVec.end(),
    for_each(?, ?, SimplerPrintFunctor() );,

    See the code below:


    #include <iostream>
    #include <string>
    #include <vector>
    #include <functional>


    class Element
    {
    public:

    Element(std::string name)
    : m_name(name)
    {}

    void printName() const
    {
    std::cout << m_name << std::endl;
    }

    private:
    std::string m_name;
    };

    class PrintFunctor : public std::unary_function<std::vector<Element*>,
    bool>
    {
    public:
    void operator()(const std::vector<Element*>& vec) const
    {
    std::for_each( vec.begin(), vec.end(),
    std::mem_fun(&Element::printName) );
    }
    };

    class SimplerPrintFunctor : public
    std::unary_function<std::vector<Element*>, bool>
    {
    public:
    void operator()(const Element* element) const
    {
    element->printName();
    }
    };

    int main()
    {
    std::vector<std::vector<Element*> > myVec;

    std::vector<Element*> tempVec;
    tempVec.push_back(new Element("e1"));
    tempVec.push_back(new Element("e2"));
    myVec.push_back(tempVec);

    for_each(myVec.begin(), myVec.end(), PrintFunctor() );

    }
    PolkaHead, Nov 28, 2006
    #1
    1. Advertising

  2. PolkaHead wrote:
    > I was wondering if there's a way to traverse a two-dimensional vector
    > (vector of vectors) with a nested for_each call.
    >
    > The code included traverses the "outer" vector with a for_each, than
    > it relies on the PrintFunctor to traverse the "inner" vector with
    > another for_each. Is it possible to nest the second for_each, so I
    > don't have to include a for_each in my function object.
    >
    > Is it possible to do a:
    > for_each(myVec.begin(), myVec.end(),
    > for_each(?, ?, SimplerPrintFunctor() );,


    If you templatize your 'SimplePrintFunctor', something like

    template<class T>
    void SimplePrintFunctor(T const& t)
    {
    t.printName();
    }

    template<class T>
    void SimplePrintFunctor(std::vector<T> const& vt)
    {
    for_each(vt.begin(), vt.end(), SimplePrintFunctor);
    }

    , it should work nicely for any nestedness of vectors. After that
    you just do

    SimplePrintFunctor(myvector);

    > [..]


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Nov 28, 2006
    #2
    1. Advertising

  3. PolkaHead

    PolkaHead Guest

    Is there a way to do it with a Functor that only acts on one element
    and not a whole vector. I was trying to avoid putting a for_each or
    any loop in the SimplePrintFunctor...


    Victor Bazarov wrote:
    > PolkaHead wrote:
    > > I was wondering if there's a way to traverse a two-dimensional vector
    > > (vector of vectors) with a nested for_each call.
    > >
    > > The code included traverses the "outer" vector with a for_each, than
    > > it relies on the PrintFunctor to traverse the "inner" vector with
    > > another for_each. Is it possible to nest the second for_each, so I
    > > don't have to include a for_each in my function object.
    > >
    > > Is it possible to do a:
    > > for_each(myVec.begin(), myVec.end(),
    > > for_each(?, ?, SimplerPrintFunctor() );,

    >
    > If you templatize your 'SimplePrintFunctor', something like
    >
    > template<class T>
    > void SimplePrintFunctor(T const& t)
    > {
    > t.printName();
    > }
    >
    > template<class T>
    > void SimplePrintFunctor(std::vector<T> const& vt)
    > {
    > for_each(vt.begin(), vt.end(), SimplePrintFunctor);
    > }
    >
    > , it should work nicely for any nestedness of vectors. After that
    > you just do
    >
    > SimplePrintFunctor(myvector);
    >
    > > [..]

    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask
    PolkaHead, Nov 28, 2006
    #3
  4. PolkaHead

    Daniel T. Guest

    "PolkaHead" <> wrote:

    > I was wondering if there's a way to traverse a two-dimensional vector
    > (vector of vectors) with a nested for_each call.
    >
    > The code included traverses the "outer" vector with a for_each, than it
    > relies on the PrintFunctor to traverse the "inner" vector with another
    > for_each. Is it possible to nest the second for_each, so I don't have
    > to include a for_each in my function object.


    If you used an Array2D class instead of nested vectors, it would be
    quite simple.

    template < typename T, typename rep_type = typename std::deque< T > >
    class Matrix
    {
    public:
    typedef typename rep_type::size_type size_type;
    typedef typename rep_type::reference reference;
    typedef typename rep_type::const_reference const_reference;
    typedef typename rep_type::iterator iterator;
    typedef typename rep_type::const_iterator const_iterator;

    Matrix(): _width( 0 ), _height( 0 ) { }
    Matrix( size_type w, size_type h ):
    _width( w ), _height( h ), _rep( w * h ) { }

    size_type width() const { return _width; }
    size_type height() const { return _height; }

    reference at( size_type x, size_type y ) {
    if ( x >= _width || y >= _height )
    throw std::eek:ut_of_range( "Matrix::at(size_type, size_type)" );
    return _rep[ x * _width + y ];
    }

    const_reference at( size_type x, size_type y ) const {
    if ( x >= _width || y >= _height )
    throw std::eek:ut_of_range( "Matrix::at(size_type, size_type)" );
    return _rep[ x * _width + y ];
    }

    iterator begin() { return _rep.begin(); }
    const_iterator begin() const { return _rep.begin(); }
    iterator end() { return _rep.end(); }
    const_iterator end() const { return _rep.end(); }

    void swap( Matrix& m ) {
    std::swap( _width, m._width );
    std::swap( _height, m._height );
    _rep.swap( m._rep );
    }

    private:
    typename rep_type::size_type _width, _height;
    rep_type _rep;
    };

    Matrix<Element> myMatrix( 2, 3 );
    // load
    for_each( myMatrix.begin(), myMatrix.end(),
    std::mem_fun( &Element::printName ) );

    --
    To send me email, put "sheltie" in the subject.
    Daniel T., Nov 29, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Black
    Replies:
    18
    Views:
    705
    Daniel T.
    Jun 16, 2004
  2. Creighton Hogg

    vector of vector of vectors

    Creighton Hogg, Jan 20, 2006, in forum: C++
    Replies:
    4
    Views:
    339
    Daniel T.
    Jan 21, 2006
  3. Replies:
    8
    Views:
    1,912
    Csaba
    Feb 18, 2006
  4. Replies:
    3
    Views:
    689
    Shadowman
    Mar 26, 2008
  5. Guest
    Replies:
    0
    Views:
    438
    Guest
    Sep 14, 2005
Loading...

Share This Page