for_each loop on a map without a functor



 DEVELOP > c-Plus-Plus > for_each loop on a map without a functor

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "nguillot"
Date: 17 Jan 2008 09:49:51 AM
Object: for_each loop on a map without a functor
Hello
I used to loop on a std::map<k, d> to act on the data (d) like that (d
being a class with setIntMember method):
typedef std::map<k, d> tMap;
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.
.

User: "Jerry Coffin"

Title: Re: for_each loop on a map without a functor 19 Jan 2008 12:34:32 AM
In article <4833611d-1e00-4984-bf4e-313b2f7fb957@
21g2000hsj.googlegroups.com>,
says...

Hello

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

typedef std::map<k, d> tMap;

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.
.

User: ""

Title: Re: for_each loop on a map without a functor 17 Jan 2008 01:19:42 PM
On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.com> wrote:

Hello

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

typedef std::map<k, d> tMap;

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)
.

User: "Daniel T."

Title: Re: for_each loop on a map without a functor 17 Jan 2008 10:59:06 AM
On Jan 17, 10:49=A0am, nguillot <nicolas.guil...@gmail.com> wrote:

Hello

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

=A0 =A0 typedef std::map<k, d> tMap;

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

The loop being:
=A0 =A0 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:

=A0 =A0 template<typename _Pair>
=A0 =A0 struct Select2nd : public unary_function<_Pair,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 typename _Pair::second=

_type>

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

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

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:
=A0 =A0 for_each(m.begin(), m.end(),
=A0 =A0 =A0 =A0 boost::bind(&d::Trace, boost::bind(&tMap::value_type::seco=

nd,

_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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );
}
for_each(m.begin(), m.end(),

callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_ref(&d::setIntMember),
4)));
.
User: "nguillot"

Title: Re: for_each loop on a map without a functor 18 Jan 2008 04:45:56 AM
On 17 jan, 17:59, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.com> wrote:



Hello


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


typedef std::map<k, d> tMap;


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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );

}

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

callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_ref(&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.
.
User: "Daniel T."

Title: Re: for_each loop on a map without a functor 18 Jan 2008 02:03:00 PM
On Jan 18, 5:45=A0am, nguillot <nicolas.guil...@gmail.com> wrote:

On 17 jan, 17:59, "Daniel T." <danie...@earthlink.net> wrote:





On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.com> wrote:


Hello


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


=A0 =A0 typedef std::map<k, d> tMap;


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


The loop being:
=A0 =A0 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:


=A0 =A0 template<typename _Pair>
=A0 =A0 struct Select2nd : public unary_function<_Pair,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 typename _Pair::se=

cond_type>

=A0 =A0 {
=A0 =A0 =A0 =A0 typename _Pair::second_type& operator()(_Pair& __x) co=

nst

=A0 =A0 =A0 =A0 { return __x.second; }


=A0 =A0 =A0 =A0 const typename _Pair::second_type& operator()(const _P=

air&

__x) const
=A0 =A0 =A0 =A0 { return __x.second; }
=A0 =A0 };


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:
=A0 =A0 for_each(m.begin(), m.end(),
=A0 =A0 =A0 =A0 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 {
=A0 =A0 Op fn;
public:
=A0 =A0 CallFuncOn2nd_t( Op fn ): fn(fn) { }
=A0 =A0 typename Op::result_type operator()( Pair& v ) const {
=A0 =A0 =A0 =A0 return fn( v.second );
=A0 =A0 }


};


template < typename Pair, typename Op >
CallFuncOn2nd_t<Pair, Op> callFuncOn2nd( Op fn ) {
=A0 =A0 return CallFuncOn2nd_t<Pair, Op>( fn );


}


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


callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_ref(&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?
.
User: "nguillot"

Title: Re: for_each loop on a map without a functor 18 Jan 2008 02:41:36 PM
On 18 jan, 21:03, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.com> wrote:



On 17 jan, 17:59, "Daniel T." <danie...@earthlink.net> wrote:


On Jan 17, 10:49 am, nguillot <nicolas.guil...@gmail.com> wrote:


Hello


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


typedef std::map<k, d> tMap;


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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );


}


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


callFuncOn2nd<tMap::value_type>(bind2nd(mem_fun_ref(&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 ?
.
User: "Daniel T."

Title: Re: for_each loop on a map without a functor 18 Jan 2008 03:13:14 PM
On Jan 18, 3:41 pm, nguillot <nicolas.guil...@gmail.com> wrote:

On 18 jan, 21:03, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.com> wrote:

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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );
}
typedef std::map<k, d> tMap;
int main(){
tMap m;
for_each(m.begin(), m.end(),

callFuncOn2nd<tMap::value_type>( bind2nd( mem_fun_ref( &d::setIntMember ),
4 ) ) );
}
=== end code ===
.
User: "nguillot"

Title: Re: for_each loop on a map without a functor 20 Jan 2008 02:08:32 PM
On 18 jan, 22:13, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 3:41 pm, nguillot <nicolas.guil...@gmail.com> wrote:

On 18 jan, 21:03, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.com> wrote:

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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );

}

typedef std::map<k, d> tMap;

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

callFuncOn2nd<tMap::value_type>( bind2nd( mem_fun_ref( &d::setIntMember ),
4 ) ) );}

=== end code ===

ARF !!
It's my fault.
I had not seen the function callOn2nd. I only saw the class!
So, ok, the code compiles (on g++).
I don't understand why we can't define only the class (if we do that
and call directly the class in the for_each:
for_each(m.begin(),
m.end(),CallFuncOn2nd_t<tMap::value_type>(bind2nd(mem_fun_ref(&d::setIntMember),
4)));
it doesn't compile:
wrong number of template arguments (1, should be 2) provided for
`template<class Pair, class Op> class CallFuncO
n2nd_t')
the same loop with the function is ok.
I would think that in
CallFuncOn2nd_t<tMap::value_type>(bind2nd(...)
the constructor would "set" the Op template arg, the second being
specified between <>.
So this solution is ok, modify the object within the map, not a
temporary.
And I think this form is not MUCH less readable than an explicit
loop ;-)
Thanks again !
An explanation on why we can't use the functor CallFuncOn2nd_t without
the function callFuncOn2nd?
.
User: "Daniel T."

Title: Re: for_each loop on a map without a functor 20 Jan 2008 05:47:00 PM
In article
<c77e194e-cdfa-44b3-bf4b-d023bd5940b8@y5g2000hsf.googlegroups.com>,
nguillot <nicolas.guillot@gmail.com> wrote:

On 18 jan, 22:13, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 3:41 pm, nguillot <nicolas.guil...@gmail.com> wrote:

On 18 jan, 21:03, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.com> wrote:

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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );

}

typedef std::map<k, d> tMap;

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

callFuncOn2nd<tMap::value_type>( bind2nd( mem_fun_ref( &d::setIntMember ),
4 ) ) );}

=== end code ===


ARF !!

It's my fault.
I had not seen the function callOn2nd. I only saw the class!
So, ok, the code compiles (on g++).

I don't understand why we can't define only the class (if we do that
and call directly the class in the for_each:
for_each(m.begin(),
m.end(),CallFuncOn2nd_t<tMap::value_type>(bind2nd(mem_fun_ref(&d::setIntMember
),
4)));
it doesn't compile:
wrong number of template arguments (1, should be 2) provided for
`template<class Pair, class Op> class CallFuncO
n2nd_t')

the same loop with the function is ok.
I would think that in
CallFuncOn2nd_t<tMap::value_type>(bind2nd(...)
the constructor would "set" the Op template arg, the second being
specified between <>.

The compiler will not infer types on template classes, only functions.
Both template parameters must be declared when using the class directly.
i.e., you would have to do this:
for_each( m.begin(), m.end(),
CallFuncOn2nd_t< tMap::value_type,
binder2nd< mem_fun1_ref_t< void, d, int> > >(
bind2nd( mem_fun_ref( &d::setIntMember ), 4 ) ) );

So this solution is ok, modify the object within the map, not a
temporary.

I think the boost bind solution is better.
.
User: "nguillot"

Title: Re: for_each loop on a map without a functor 28 Jan 2008 06:34:19 AM
On 21 jan, 00:47, "Daniel T." <danie...@earthlink.net> wrote:

In article
<c77e194e-cdfa-44b3-bf4b-d023bd594...@y5g2000hsf.googlegroups.com>,



nguillot <nicolas.guil...@gmail.com> wrote:

On 18 jan, 22:13, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 3:41 pm, nguillot <nicolas.guil...@gmail.com> wrote:


On 18 jan, 21:03, "Daniel T." <danie...@earthlink.net> wrote:

On Jan 18, 5:45 am, nguillot <nicolas.guil...@gmail.com> wrote:

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, Op> callFuncOn2nd( Op fn ) {
return CallFuncOn2nd_t<Pair, Op>( fn );


}


typedef std::map<k, d> tMap;


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


callFuncOn2nd<tMap::value_type>( bind2nd( mem_fun_ref( &d::setIntMember ),
4 ) ) );}


=== end code ===


ARF !!


It's my fault.
I had not seen the function callOn2nd. I only saw the class!
So, ok, the code compiles (on g++).


I don't understand why we can't define only the class (if we do that
and call directly the class in the for_each:
for_each(m.begin(),
m.end(),CallFuncOn2nd_t<tMap::value_type>(bind2nd(mem_fun_ref(&d::setIntMember
),
4)));
it doesn't compile:
wrong number of template arguments (1, should be 2) provided for
`template<class Pair, class Op> class CallFuncO
n2nd_t')


the same loop with the function is ok.
I would think that in
CallFuncOn2nd_t<tMap::value_type>(bind2nd(...)
the constructor would "set" the Op template arg, the second being
specified between <>.


The compiler will not infer types on template classes, only functions.
Both template parameters must be declared when using the class directly.
i.e., you would have to do this:

for_each( m.begin(), m.end(),
CallFuncOn2nd_t< tMap::value_type,
binder2nd< mem_fun1_ref_t< void, d, int> > >(
bind2nd( mem_fun_ref( &d::setIntMember ), 4 ) ) );

So this solution is ok, modify the object within the map, not a
temporary.


I think the boost bind solution is better.

About the boost solution,
don't you have the following error:
main.cpp:84: instantiated from here
../boost/bind/mem_fn_template.hpp:148: error: invalid conversion from
`const Foo*
' to `Foo*'
See boost doc about this problem: http://www.boost.org/libs/bind/bind.html#Limitations
Your code compiles and works on visual studi VC++6.0
But it doesn't on g++ and on visual studio 2005.
Which compiler did you use?
Thank you
Nicolas
.
User: "Daniel T."

Title: Re: for_each loop on a map without a functor 28 Jan 2008 05:37:30 PM
nguillot <nicolas.guillot@gmail.com> wrote:

About the boost solution,
don't you have the following error:

main.cpp:84: instantiated from here
./boost/bind/mem_fn_template.hpp:148: error: invalid conversion from
`const Foo*
' to `Foo*'

No, I don't. Let's make sure we are talking about the same code...
using namespace std;
using namespace boost::lambda;
class Foo {
public:
void bar( int i ) { }
};
typedef map<int, Foo> map_t;
int main() {
map_t pot;
for_each( pot.begin(), pot.end(),
bind( &Foo::bar, bind(&map_t::value_type::second, _1 ), 4 ) );
}

See boost doc about this problem:
http://www.boost.org/libs/bind/bind.html#Limitations

Your code compiles and works on visual studi VC++6.0
But it doesn't on g++ and on visual studio 2005.

Which compiler did you use?

gcc 4.0.
.
User: "nguillot"

Title: Re: for_each loop on a map without a functor 29 Jan 2008 07:51:31 AM
On 29 jan, 00:37, "Daniel T." <danie...@earthlink.net> wrote:

nguillot <nicolas.guil...@gmail.com> wrote:

About the boost solution,
don't you have the following error:


main.cpp:84: instantiated from here
./boost/bind/mem_fn_template.hpp:148: error: invalid conversion from
`const Foo*
' to `Foo*'


No, I don't. Let's make sure we are talking about the same code...

using namespace std;
using namespace boost::lambda;

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

};

typedef map<int, Foo> map_t;

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

}

See boost doc about this problem:
http://www.boost.org/libs/bind/bind.html#Limitations


Your code compiles and works on visual studi VC++6.0
But it doesn't on g++ and on visual studio 2005.


Which compiler did you use?


gcc 4.0.

Hello
My fault again, I was using boost::bind instead of
boost::lambda::bind.
This time, it's good.
Thank you very much!
Nicolas.
.










User: "shunsuke"

Title: Re: for_each loop on a map without a functor 18 Jan 2008 07:57:01 PM
On Jan 18, 12:49 am, nguillot <nicolas.guil...@gmail.com> wrote:

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
.

User: "Daniel T."

Title: Re: for_each loop on a map without a functor 18 Jan 2008 10:10:28 PM
nguillot <nicolas.guil...@gmail.com> wrote:

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

typedef std::map<k, d> tMap;

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, Foo> map_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.
.


  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER