Fail to understand std::transform

V

Vijai Kalyan

Hello,

I am trying to use std::transform to take in a collection of strings,
transform them and insert the result into an output container. So, I
wrote something like this:

std::wstring doSomething (std::wstring const& str)
{
// do something to copy of str and return new value
}

void foo ()
{
std::set<std::wstring> input;
std::set<std::wstring> output;

std::transform (input.begin(), input.end(), output.begin(),
doSomething);
}

I stepped into the implementation of std::transform (on my platform)
and it goes something like:-

template<class _InIt,
class _OutIt,
class _Fn1> inline
_OutIt transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
{ // transform [_First, _Last) with _Func
for (; _First != _Last; ++_First, ++_Dest)
*_Dest = _Func(*_First);
return (_Dest);
}

It looks like the

*_Dest = _Func (*_First)

would mean that transform expects the output objects to already exist.
Is that right? I keep crashing at the assignment. Does std::transform
require sequence containers with pre-reserved sizes?

thanks,

-vijai.
 
V

Vijai Kalyan

Doh!

The documentation says that the output range must be valid. THen the
question becomes:-

I got a bunch of objects. I have to transform them in some way and
insert them into a destination. How would I do that?

-vijai.
 
V

Vijai Kalyan

Doh!

The documentation says that the output range must be valid. THen the
question becomes:-

I got a bunch of objects. I have to transform them in some way and
insert them into a destination. How would I do that?

-vijai.
 
D

Daniel T.

Vijai Kalyan said:
Hello,

I am trying to use std::transform to take in a collection of strings,
transform them and insert the result into an output container. So, I
wrote something like this:

std::wstring doSomething (std::wstring const& str)
{
// do something to copy of str and return new value
}

void foo ()
{
std::set<std::wstring> input;
std::set<std::wstring> output;

std::transform (input.begin(), input.end(), output.begin(),
doSomething);
}

I stepped into the implementation of std::transform (on my platform)
and it goes something like:-

template<class _InIt,
class _OutIt,
class _Fn1> inline
_OutIt transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
{ // transform [_First, _Last) with _Func
for (; _First != _Last; ++_First, ++_Dest)
*_Dest = _Func(*_First);
return (_Dest);
}

It looks like the

*_Dest = _Func (*_First)

would mean that transform expects the output objects to already exist.
Is that right? I keep crashing at the assignment. Does std::transform
require sequence containers with pre-reserved sizes?

Either that or you have to use an appropriate iterator adaptor. You
could do a number of things:

transform( input.begin(), input.end(), input.begin(), &doSomething );

This assumes you won't need the input after the transform is done. If
you do, then use an inserter...

vector<wstring> output;
transform( input.begin(), input.end(),
back_inserter( output ), &doSomething );

The back_insert_iterator converts assignment into a push_back. There is
also a front_inserter and an inserter.

http://www.sgi.com/tech/stl/back_insert_iterator.html
http://www.sgi.com/tech/stl/front_insert_iterator.html
and
http://www.sgi.com/tech/stl/insert_iterator.html
 
O

Old Wolf

Daniel said:
transform( input.begin(), input.end(), input.begin(), &doSomething );

I don't think this is valid for a set -- the transformation might
mess up the set's ordering (if it even lets you write to input.begin())
 
R

red floyd

Vijai said:
Doh!

The documentation says that the output range must be valid. THen the
question becomes:-

I got a bunch of objects. I have to transform them in some way and
insert them into a destination. How would I do that?

-vijai.

std::back_inserter()
 
D

Daniel T.

Old Wolf said:
I don't think this is valid for a set -- the transformation might
mess up the set's ordering (if it even lets you write to
input.begin())

It wouldn't even compile if 'input' is a set.
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top