Modifying the value of each element stored in a std::vector.

J

Jason Heyes

Look at my code:

void modify_element(BigType &x)
{
/* not shown */
}

BigType modify_element_copy(BigType x)
{
modify_element(x);
return x;
}

void modify_container(std::vector<BigType> &v)
{
std::transform(v.begin(), v.end(), v.begin(), modify_element_copy);
}

Can I replace the call to std::tranform with a call to std::for_each? My
documentation says that for_each must not modify the elements. Here is
modify_container using std::for_each rather than std::transform:

void modify_container(std::vector<BigType> &v)
{
std::for_each(v.begin(), v.end(), modify_element);
}

Any help is appreciated.
 
M

Mike Wahler

Jason Heyes said:
Look at my code:

void modify_element(BigType &x)
{
/* not shown */
}

BigType modify_element_copy(BigType x)
{
modify_element(x);
return x;
}

void modify_container(std::vector<BigType> &v)
{
std::transform(v.begin(), v.end(), v.begin(), modify_element_copy);
}

Can I replace the call to std::tranform with a call to std::for_each? My
documentation says that for_each must not modify the elements.
Here is
modify_container using std::for_each rather than std::transform:

void modify_container(std::vector<BigType> &v)
{
std::for_each(v.begin(), v.end(), modify_element);
}

Yes, 'for_each()' should work fine. Just remember not to try
using a modifying predicate with a const vector or via
const_iterators (well, the compiler should complain if you
do anyway).

-Mike
 
J

Jason Heyes

Mike Wahler said:
Yes, 'for_each()' should work fine. Just remember not to try
using a modifying predicate with a const vector or via
const_iterators (well, the compiler should complain if you
do anyway).

-Mike

Ok thanks for that.
 
M

Matthew Schaefer

The for_each algorithm does not modify the elements of the sequence. It
calls Function F for each element in the range [First, Last) and
returns the input parameter F. This function does not modify any
elements in the sequence.
 
J

Jason Heyes

Matthew Schaefer said:
The for_each algorithm does not modify the elements of the sequence. It

calls Function F for each element in the range [First, Last) and
returns the input parameter F. This function does not modify any
elements in the sequence. See "The Difference between for_each and
transform", C/C++ Users Journal, February 2001, Klaus Kreft &
Angelika Langer.

http://www.langer.camelot.de/Articles/Cuj/03.ForeachTransform/ForEachTransform.html

I read the article and it contradicts what you just said. It states that
for_each "permits side effects including modification of elements from the
input sequence." You said "this function does not modify any elements in the
sequence." What is right?
 
R

Richard Herring

In message said:
The for_each algorithm does not modify the elements of the sequence. It
calls Function F for each element in the range [First, Last) and
returns the input parameter F. This function does not modify any
elements in the sequence.

The *algorithm* does not, of itself, modify any elements of the
sequence, and it discards the result of function F. That doesn't prevent
the function F from modifying its argument if you pass iterators of an
appropriate type.
 
J

Jason Heyes

Richard Herring said:
In message said:
The for_each algorithm does not modify the elements of the sequence. It
calls Function F for each element in the range [First, Last) and
returns the input parameter F. This function does not modify any
elements in the sequence.

The *algorithm* does not, of itself, modify any elements of the sequence,
and it discards the result of function F. That doesn't prevent the
function F from modifying its argument if you pass iterators of an
appropriate type.

The result of F eventually comes back as a return value, I believe.
 
R

Richard Herring

Jason Heyes said:
Richard Herring said:
In message said:
The for_each algorithm does not modify the elements of the sequence. It
calls Function F for each element in the range [First, Last) and
returns the input parameter F. This function does not modify any
elements in the sequence.

The *algorithm* does not, of itself, modify any elements of the sequence,
and it discards the result of function F. That doesn't prevent the
function F from modifying its argument if you pass iterators of an
appropriate type.

The result of F eventually comes back as a return value, I believe.
No. A copy of F itself (the functor or function pointer) is returned:

template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f)
{
while (first != last) f(*first++);
return f;
}
 
M

Mike Wahler

Matthew Schaefer said:
The for_each algorithm does not modify the elements of the sequence.

It calls the user supplied predicate function once for
each element, passing it a reference to the element.
The function can modify the referred to object if it likes.
It calls Function F for each element in the range [First, Last) and
returns the input parameter F.
This function does not modify any
elements in the sequence. See "The Difference between for_each and
transform", C/C++ Users Journal, February 2001, Klaus Kreft &
Angelika Langer.
http://www.langer.camelot.de/Articles/Cuj/03.ForeachTransform/ForEachTransfo
rm.html

Read it again. :)

-Mike
 
M

Mike Wahler

Richard Herring said:
Jason Heyes said:
Richard Herring said:
In message <[email protected]>,
The for_each algorithm does not modify the elements of the sequence. It
calls Function F for each element in the range [First, Last) and
returns the input parameter F. This function does not modify any
elements in the sequence.

The *algorithm* does not, of itself, modify any elements of the sequence,
and it discards the result of function F. That doesn't prevent the
function F from modifying its argument if you pass iterators of an
appropriate type.

The result of F eventually comes back as a return value, I believe.
No. A copy of F itself (the functor or function pointer) is returned:

template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f)
{
while (first != last) f(*first++);
return f;
}

Jason: Also note that if f() does return a value, it is
ignored. (So there's no point in f() having a return type
other than 'void', unless one plans to use it in other
contexts where the return value would be available).



-Mike
 
J

Jason Heyes

Richard Herring said:
No. A copy of F itself (the functor or function pointer) is returned:

template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f)
{
while (first != last) f(*first++);
return f;
}

Oh yea. Quite right.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top