How to write the transform equivalent in STL?

B

benben

I have the following code snippet:

class converter
{
// ...
public:
virtual polar_point convert_to_polar(const point&) = 0;
};

void f(const std::vector<point>& points, converter& cvt)
{
vector<polar_point> polarpoints(points.size());

for (unsigned int i = 0; i < points.size(); ++i)
{
polarpoints = cvt.convert(points);
}

print_points(polarpoints);

// ...
}


I'd like to replace the for loop with an appropriate std::transform
call. But I can't figure out what functor should I pass to transform...I
am thinking a number of combinations of mem_fun and bind1st/bind2nd, but
they don't seem to work.

Any ideas?

Ben
 
D

Daniel T.

benben said:
I have the following code snippet:

class converter
{
// ...
public:
virtual polar_point convert_to_polar(const point&) = 0;
};

void f(const std::vector<point>& points, converter& cvt)
{
vector<polar_point> polarpoints(points.size());

for (unsigned int i = 0; i < points.size(); ++i)
{
polarpoints = cvt.convert(points);
}

print_points(polarpoints);

// ...
}


I'd like to replace the for loop with an appropriate std::transform
call. But I can't figure out what functor should I pass to transform...I
am thinking a number of combinations of mem_fun and bind1st/bind2nd, but
they don't seem to work.

Any ideas?


transform( points.begin(), points.end(), polarpoints.begin(),
bind1st( mem_fun( &converter::convert_to_polar ), &cvt ) );

However the above will only work if you change the converter...

class converter
{
// ...
public:
virtual polar_point convert_to_polar(point) = 0;
// parameter no longer a const point&
};

Note that:

transform( points.begin(), points.end(), polarpoints.begin(),
bind1st( mem_fun_ref( &converter::convert_to_polar ), cvt ) );

Won't work because converter is an ABC.
 
B

benben

transform( points.begin(), points.end(), polarpoints.begin(),
bind1st( mem_fun( &converter::convert_to_polar ), &cvt ) );


Thanks, that worked!
However the above will only work if you change the converter...

class converter
{
// ...
public:
virtual polar_point convert_to_polar(point) = 0;
// parameter no longer a const point&
};

Hmm, can you elaborate a little bit more or point me to an article on
this. This bothers me because the calling to a function taking a const
reference or value should at least look the same at call site...perhaps
it is the parameter forwarding that causes this restriction...but anyway
I am not quite sure...more research to do.
Note that:

transform( points.begin(), points.end(), polarpoints.begin(),
bind1st( mem_fun_ref( &converter::convert_to_polar ), cvt ) );

Won't work because converter is an ABC.

Yup, I am using a specific converter function from a derived class.

Thank you!

Ben
 
N

Noah Roberts

benben said:
Thanks, that worked!


Hmm, can you elaborate a little bit more or point me to an article on
this. This bothers me because the calling to a function taking a const
reference or value should at least look the same at call site...perhaps
it is the parameter forwarding that causes this restriction...but anyway
I am not quite sure...more research to do.

bind1st and bind2nd add a reference to T, T being whatever type is the
parameter in the target function call. This reference is accepted as
the resulting functor's parameter. Essentially you have:

template <typename X, typename R, typename T>
struct binder2nd
{
X * x;
R operator()(T & t) { return x->functionName(t); }
};

Of course the actual definition isn't the above but that is the gist of
the problem. What happens then if your function accepts a reference is
that T is then a reference and so operator() in the binder accepts a
reference reference, which is not a legal type. The code then won't
compile.

The TR1 bind setup does better I believe.
 
D

Daniel T.

transform( points.begin(), points.end(), polarpoints.begin(),
bind1st( mem_fun( &converter::convert_to_polar ), &cvt ) );


Thanks, that worked!
However the above will only work if you change the converter...

class converter
{
// ...
public:
virtual polar_point convert_to_polar(point) = 0;
// parameter no longer a const point&
};

Hmm, can you elaborate a little bit more or point me to an article on
this. This bothers me because the calling to a function taking a const
reference or value should at least look the same at call site...perhaps
it is the parameter forwarding that causes this restriction...but anyway
I am not quite sure...more research to do.[/QUOTE]

As Noah already detailed. Making the parameter a reference will cause a
reference to reference type which isn't allowed.

Also, in this specific case, I'd more likely use generate_n instead of
transform.
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top