Using for_each with a vector of vectors

P

PolkaHead

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() );

}
 
V

Victor Bazarov

PolkaHead said:
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
 
P

PolkaHead

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 said:
PolkaHead said:
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
 
D

Daniel T.

PolkaHead said:
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 ) );
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top