By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,307 Members | 2,094 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,307 IT Pros & Developers. It's quick & easy.

for_each loop on a map without a functor

P: n/a
Hello

I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):

typedef std::map<k, dtMap;

struct setIntMember
{
setIntMember(int j) : i(j) {}
void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
int i;
};

The loop being:
for_each(m.begin(), m.end(), setIntMember(4));

I searched for a method to write all in the for_each loop (to avoid
increasing the functors).

We need a function returning the second member of the pair
tMap::value_type,
and their is the SGI template:

template<typename _Pair>
struct Select2nd : public unary_function<_Pair,
typename _Pair::second_type>
{
typename _Pair::second_type& operator()(_Pair& __x) const
{ return __x.second; }

const typename _Pair::second_type& operator()(const _Pair&
__x) const
{ return __x.second; }
};

But I didn't manage to write a single line to perform the for_each
loop, thanks to Select2nd with for_each, bind2nd and mem_fun and
mem_fun1

I didn't manage with boost::bind (on VC++ 6.0):
With boost, I can access the objects like that:
for_each(m.begin(), m.end(),
boost::bind(&d::Trace, boost::bind(&tMap::value_type::second,
_1)));
but the d::Trace method is called on a temporary object, so I cannot
modify the content of the objects contained in the map.

Some ideas? Thanks in advance.

Nicolas.
Jan 17 '08 #1
Share this Question
Share on Google+
9 Replies


P: n/a
On Jan 17, 10:49*am, nguillot <nicolas.guil...@gmail.comwrote:
Hello

I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):

* * typedef std::map<k, dtMap;

* * struct setIntMember
* * {
* * * * setIntMember(int j) : i(j) {}
* * * * void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
* * * * int i;
* * };

The loop being:
* * for_each(m.begin(), m.end(), setIntMember(4));

I searched for a method to write all in the for_each loop (to avoid
increasing the functors).

We need a function returning the second member of the pair
tMap::value_type,
and their is the SGI template:

* * template<typename _Pair>
* * struct Select2nd : public unary_function<_Pair,
* * * * * * * * * * * * * typename _Pair::second_type>
* * {
* * * * typename _Pair::second_type& operator()(_Pair& __x) const
* * * * { return __x.second; }

* * * * const typename _Pair::second_type& operator()(const _Pair&
__x) const
* * * * { return __x.second; }
* * };

But I didn't manage to write a single line to perform the for_each
loop, thanks to Select2nd with for_each, bind2nd and mem_fun and
mem_fun1

I didn't manage with boost::bind (on VC++ 6.0):
With boost, I can access the objects like that:
* * for_each(m.begin(), m.end(),
* * * * boost::bind(&d::Trace, boost::bind(&tMap::value_type::second,
_1)));
but the d::Trace method is called on a temporary object, so I cannot
modify the content of the objects contained in the map.

Some ideas?
Just use the functor you created. It's simple and clean... You might
want to generalized it a little bit:

template < typename Pair, typename Op >
class CallFuncOn2nd_t {
Op fn;
public:
CallFuncOn2nd_t( Op fn ): fn(fn) { }
typename Op::result_type operator()( Pair& v ) const {
return fn( v.second );
}
};

template < typename Pair, typename Op >
CallFuncOn2nd_t<Pair, OpcallFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );
}

for_each(m.begin(), m.end(),

callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_re f(&d::setIntMember),
4)));

Jan 17 '08 #2

P: n/a
On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.comwrote:
Hello

I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):

typedef std::map<k, dtMap;

struct setIntMember
{
setIntMember(int j) : i(j) {}
void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
int i;
};

The loop being:
for_each(m.begin(), m.end(), setIntMember(4));

I searched for a method to write all in the for_each loop (to avoid
increasing the functors).
[snip]
>
I didn't manage with boost::bind (on VC++ 6.0):
With boost, I can access the objects like that:
for_each(m.begin(), m.end(),
boost::bind(&d::Trace, boost::bind(&tMap::value_type::second,
_1)));
but the d::Trace method is called on a temporary object, so I cannot
modify the content of the objects contained in the map.
For the boost::bind part, your case looks very much like what is
discussed here: http://lists.boost.org/boost-users/2007/01/24599.php
(Look at Peter Dimov's reply)
Jan 17 '08 #3

P: n/a
On 17 jan, 17:59, "Daniel T." <danie...@earthlink.netwrote:
On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.comwrote:
Hello
I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):
typedef std::map<k, dtMap;
struct setIntMember
{
setIntMember(int j) : i(j) {}
void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
int i;
};
The loop being:
for_each(m.begin(), m.end(), setIntMember(4));
I searched for a method to write all in the for_each loop (to avoid
increasing the functors).
We need a function returning the second member of the pair
tMap::value_type,
and their is the SGI template:
template<typename _Pair>
struct Select2nd : public unary_function<_Pair,
typename _Pair::second_type>
{
typename _Pair::second_type& operator()(_Pair& __x) const
{ return __x.second; }
const typename _Pair::second_type& operator()(const _Pair&
__x) const
{ return __x.second; }
};
But I didn't manage to write a single line to perform the for_each
loop, thanks to Select2nd with for_each, bind2nd and mem_fun and
mem_fun1
I didn't manage with boost::bind (on VC++ 6.0):
With boost, I can access the objects like that:
for_each(m.begin(), m.end(),
boost::bind(&d::Trace, boost::bind(&tMap::value_type::second,
_1)));
but the d::Trace method is called on a temporary object, so I cannot
modify the content of the objects contained in the map.
Some ideas?

Just use the functor you created. It's simple and clean... You might
want to generalized it a little bit:

template < typename Pair, typename Op >
class CallFuncOn2nd_t {
Op fn;
public:
CallFuncOn2nd_t( Op fn ): fn(fn) { }
typename Op::result_type operator()( Pair& v ) const {
return fn( v.second );
}

};

template < typename Pair, typename Op >
CallFuncOn2nd_t<Pair, OpcallFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );

}

for_each(m.begin(), m.end(),

callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_re f(&d::setIntMember),
4)));
Ok, thanks, that's was exactly what I wanted to do!

But callFuncOn2nd<tMap::value_type>(bind2nd... fails to compile: the
second template argument seems to be required.
We must set the second template argument as a class that
has ::result_type, so I tried a std::unary_function<d, bool(if
d::setIntMember returns a bool), but even if bind2nd could be
converted to unary_function (what fails) a unary function doesn't have
a () operator.
And I didn't manage write the second argument to be
std::binder2nd<std::binary_function<d*, int, bool or something like
that: it doesn't compile.

So the question: how write the for_each line?
Or how to modify the callFuncOn2nd to auto discover the type (that
woulkd be nice, but as Op is the typeof fn (member of the class), we
have to put Op a a class template argument...

Thanks for help.

Nicolas.
Jan 18 '08 #4

P: n/a
On Jan 18, 5:45*am, nguillot <nicolas.guil...@gmail.comwrote:
On 17 jan, 17:59, "Daniel T." <danie...@earthlink.netwrote:


On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.comwrote:
Hello
I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):
* * typedef std::map<k, dtMap;
* * struct setIntMember
* * {
* * * * setIntMember(int j) : i(j) {}
* * * * void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
* * * * int i;
* * };
The loop being:
* * for_each(m.begin(), m.end(), setIntMember(4));
I searched for a method to write all in the for_each loop (to avoid
increasing the functors).
We need a function returning the second member of the pair
tMap::value_type,
and their is the SGI template:
* * template<typename _Pair>
* * struct Select2nd : public unary_function<_Pair,
* * * * * * * * * * * * * typename _Pair::second_type>
* * {
* * * * typename _Pair::second_type& operator()(_Pair& __x) const
* * * * { return __x.second; }
* * * * const typename _Pair::second_type& operator()(const _Pair&
__x) const
* * * * { return __x.second; }
* * };
But I didn't manage to write a single line to perform the for_each
loop, thanks to Select2nd with for_each, bind2nd and mem_fun and
mem_fun1
I didn't manage with boost::bind (on VC++ 6.0):
With boost, I can access the objects like that:
* * for_each(m.begin(), m.end(),
* * * * boost::bind(&d::Trace, boost::bind(&tMap::value_type::second,
_1)));
but the d::Trace method is called on a temporary object, so I cannot
modify the content of the objects contained in the map.
Some ideas?
Just use the functor you created. It's simple and clean... You might
want to generalized it a little bit:
template < typename Pair, typename Op >
class CallFuncOn2nd_t {
* * Op fn;
public:
* * CallFuncOn2nd_t( Op fn ): fn(fn) { }
* * typename Op::result_type operator()( Pair& v ) const {
* * * * return fn( v.second );
* * }
};
template < typename Pair, typename Op >
CallFuncOn2nd_t<Pair, OpcallFuncOn2nd( Op fn ) {
* * return CallFuncOn2nd_t<Pair, Op>( fn );
}
for_each(m.begin(), m.end(),
callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_re f(&d::setIntMember),
4)));

Ok, thanks, that's was exactly what I wanted to do!

But callFuncOn2nd<tMap::value_type>(bind2nd... fails to compile: the
second template argument seems to be required.
We must set the second template argument as a class that
has ::result_type, so I tried a std::unary_function<d, bool(if
d::setIntMember returns a bool), but even if bind2nd could be
converted to unary_function (what fails) a unary function doesn't have
a () operator.
And I didn't manage write the second argument to be
std::binder2nd<std::binary_function<d*, int, bool or something like
that: it doesn't compile.

So the question: how write the for_each line?
Hmm, the for_each line I wrote above compiles fine for me. What
compiler are you using?
Jan 18 '08 #5

P: n/a
On 18 jan, 21:03, "Daniel T." <danie...@earthlink.netwrote:
On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.comwrote:
On 17 jan, 17:59, "Daniel T." <danie...@earthlink.netwrote:
On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.comwrote:
Hello
I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):
typedef std::map<k, dtMap;
struct setIntMember
{
setIntMember(int j) : i(j) {}
void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
int i;
};
The loop being:
for_each(m.begin(), m.end(), setIntMember(4));
I searched for a method to write all in the for_each loop (to avoid
increasing the functors).
We need a function returning the second member of the pair
tMap::value_type,
and their is the SGI template:
template<typename _Pair>
struct Select2nd : public unary_function<_Pair,
typename _Pair::second_type>
{
typename _Pair::second_type& operator()(_Pair& __x) const
{ return __x.second; }
const typename _Pair::second_type& operator()(const _Pair&
__x) const
{ return __x.second; }
};
But I didn't manage to write a single line to perform the for_each
loop, thanks to Select2nd with for_each, bind2nd and mem_fun and
mem_fun1
I didn't manage with boost::bind (on VC++ 6.0):
With boost, I can access the objects like that:
for_each(m.begin(), m.end(),
boost::bind(&d::Trace, boost::bind(&tMap::value_type::second,
_1)));
but the d::Trace method is called on a temporary object, so I cannot
modify the content of the objects contained in the map.
Some ideas?
Just use the functor you created. It's simple and clean... You might
want to generalized it a little bit:
template < typename Pair, typename Op >
class CallFuncOn2nd_t {
Op fn;
public:
CallFuncOn2nd_t( Op fn ): fn(fn) { }
typename Op::result_type operator()( Pair& v ) const {
return fn( v.second );
}
};
template < typename Pair, typename Op >
CallFuncOn2nd_t<Pair, OpcallFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );
}
for_each(m.begin(), m.end(),
callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_re f(&d::setIntMember),
4)));
Ok, thanks, that's was exactly what I wanted to do!
But callFuncOn2nd<tMap::value_type>(bind2nd... fails to compile: the
second template argument seems to be required.
We must set the second template argument as a class that
has ::result_type, so I tried a std::unary_function<d, bool(if
d::setIntMember returns a bool), but even if bind2nd could be
converted to unary_function (what fails) a unary function doesn't have
a () operator.
And I didn't manage write the second argument to be
std::binder2nd<std::binary_function<d*, int, bool or something like
that: it doesn't compile.
So the question: how write the for_each line?

Hmm, the for_each line I wrote above compiles fine for me. What
compiler are you using?
I tried on VC++ 6.0 and on visual studio 2005...
and you ?
Jan 18 '08 #6

P: n/a
On Jan 18, 3:41 pm, nguillot <nicolas.guil...@gmail.comwrote:
On 18 jan, 21:03, "Daniel T." <danie...@earthlink.netwrote:
On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.comwrote:
So the question: how write the for_each line?
Hmm, the for_each line I wrote above compiles fine for me. What
compiler are you using?

I tried on VC++ 6.0 and on visual studio 2005...
and you
Visual Sutdio 2005 compiles the following just fine:
=== begine code ===
#include <algorithm>
#include <map>

using namespace std;

typedef int k;

class d {
public:
void setIntMember( int i ) { }
};

template < typename Pair, typename Op >
class CallFuncOn2nd_t {
Op fn;
public:
CallFuncOn2nd_t( Op fn ): fn(fn) { }
typename Op::result_type operator()( Pair& v ) const {
return fn( v.second );
}
};

template < typename Pair, typename Op >
CallFuncOn2nd_t<Pair, OpcallFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );
}

typedef std::map<k, dtMap;

int main(){
tMap m;
for_each(m.begin(), m.end(),

callFuncOn2nd<tMap::value_type>( bind2nd( mem_fun_ref( &d::setIntMember ),
4 ) ) );
}
=== end code ===
Jan 18 '08 #7

P: n/a
On Jan 18, 12:49 am, nguillot <nicolas.guil...@gmail.comwrote:
Some ideas? Thanks in advance.

Nicolas.
If you are brave enough to use my radical library:
http://p-stade.sourceforge.net/oven/index.html

PSTADE_OVEN_FOREACH (v, m|oven::map_values) {
// use and modify v...
}
Regards,

--
Shunsuke Sogame
Jan 19 '08 #8

P: n/a
nguillot <nicolas.guil...@gmail.comwrote:
I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):

typedef std::map<k, dtMap;

struct setIntMember
{
setIntMember(int j) : i(j) {}
void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
int i;
};

The loop being:
for_each(m.begin(), m.end(), setIntMember(4));

I searched for a method to write all in the for_each loop (to avoid
increasing the functors).

Some ideas? Thanks in advance.
I finally got it...

class Foo {
public:
void bar( int i ) { }
};

typedef map<int, Foomap_t;

int main() {
map_t pot;
for_each( pot.begin(), pot.end(),
bind( &Foo::bar, bind(&map_t::value_type::second, _1 ), 4 ) );
}

I verified that this does in fact call Foo::bar on the object within
the map, not on a temporary.

Jan 19 '08 #9

P: n/a
In article <4833611d-1e00-4984-bf4e-313b2f7fb957@
21g2000hsj.googlegroups.com>, ni*************@gmail.com says...
Hello

I used to loop on a std::map<k, dto act on the data (d) like that (d
being a class with setIntMember method):

typedef std::map<k, dtMap;

struct setIntMember
{
setIntMember(int j) : i(j) {}
void operator()(tMap::value_type& pair)
{ pair.second.setIntMember(i); }
int i;
};

The loop being:
for_each(m.begin(), m.end(), setIntMember(4));

I searched for a method to write all in the for_each loop (to avoid
increasing the functors).
In this case, I'm pretty sure a simple for loop is really much more
readable than anything using for_each:

for (std::map<k,d>::iterator p=m.begin(), p!=m.end(), ++p)
p->second = 4;

Boost::lambda is often useful when you want to avoid (explicitly)
creating a functor, but I don't believe it works for this particular
case. As we've already seen in the rest of the thread, the code to make
for_each do the job ends up ugly and MUCH less readable than an explicit
loop. I know we'd all like to use an algorithm, but in this case the
cost is high and the benefit essentially nonexistent.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jan 19 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.