Boost logo

Boost Users :

From: Robert Mathews (rmathews_at_[hidden])
Date: 2005-07-01 15:14:44


Yes, that's what I needed, thank you very much. FWIW, I couldn't find
make_function_output_iterator when I first looked at the documentation, and
then I ended out trying to read the code in the iterators library instead
... which was about when I gave up and posted.

I rewrote it as follows, binding to the convert function and then sending
that result to the push_back, and it now looks like the following.
Unfortunately, vector::push_back is overloaded, so that the cast is really
ugly. But it works.

int _tmain(int argc, _TCHAR* argv[])
{
 V1 aSourceVector;
 V2 aTargetVector;
 aSourceVector.push_back(43);

 copy(aSourceVector.begin(),
          aSourceVector.end(),
          make_function_output_iterator(
                         boost::bind((void (vector<string>::*)(const
string&))&vector<string>::push_back,
                                           boost::ref(aTargetVector),
                                           boost::bind(convert,_1))));
}

"David Abrahams" <dave_at_[hidden]> wrote in message
news:u4qbfc7k9.fsf_at_boost-consulting.com...
> "Robert Mathews" <rmathews_at_[hidden]> writes:
>
> > How does this work?
> >
> > I'm trying to use the make_transform_iterator to make a writeable output
> > iterator (looks like it is referred to as a "Writeable LValue" in the
> > iterator template code
>
> Don't look at the code; read the documentation. The meaning of
> "writeable lvalue iterator" is detailed in the paper here:
> http://www.boost.org/libs/iterator/doc/index.html#new-style-iterators
>
> > ), but I can't figure out how to do it.
> >
> > Here's the example: (I know that I could have used the
> > make_transform_iterators on the source iterators in this toy example,
but
> > that won't do for my real application)
> >
> > typedef map<int,string> Map;
> > typedef vector<int> V1;
> > typedef vector<string> V2;
> > string convert(int iValue)
> > {
> > return str(ostringstream() << iValue);
> > }
> >
> > int _tmain(int argc, _TCHAR* argv[])
> > {
> > V1 aSourceVector;
> > V2 aTargetVector;
> > copy(aSourceVector.begin(), aSourceVector.end(),
> > make_transform_iterator(back_inserter(aTargetVector),
boost::bind(convert,
> > _1));
> > }
>
> Okay, let's review what a transform_iterator does, from
> http://www.boost.org/libs/iterator/doc/transform_iterator.html:
>
> The transform iterator adapts an iterator by modifying the operator*
> to apply a function object to the result of dereferencing the
> iterator and returning the result.
>
> So your transform_iterator's operator* is going to apply convert to
> the result of dereferencing a back_insert_iterator. Okay, that's your
> first problem. Do you know what you get when you dereference a
> back_insert_iterator?
>
> According to my copy of the standard, back_insert_iterator's operator*
> has the following signature:
>
> back_insert_iterator<Container>& operator*();
>
> In other words, it returns a reference to a back_insert_iterator.
> Since convert takes an int, you have an impedance mismatch.
>
> Sounds like you want something more like function_output_iterator:
> http://www.boost.org/libs/iterator/doc/function_output_iterator.html
>
> It doesn't adapt an iterator, and I'm guessing you don't really want
> to adapt an iterator anyway (you could just use push_back, or more
> likely in your case, operator<<), but if I'm wrong, you can always
> embed the iterator in the function object you adapt.
>
> HTH,
>
> --
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net