I just read in the C++ standard that std::for_each
is a non-modifying sequence operation, along with find
, search
and so on. Does that mean that the function applied to each element should not modify them? Why is that? What could possibly go wrong?
Here is a sample code, where the sequence is modified. Can you see anything wrong with it?
void foo(int & i)
{
i = 12;
}
int main()
{
std::vector<int> v;
v.push_back(0);
std::for_each(v.begin(), v.end(), foo);
// v now contains 12
}
I suspect this to be just an interpretation issue, but I wanted to have your opinion about that.
PS: I know I could use std::transform
instead of for_each
, but that's not the point.
Quite simply, you can't make a change that could modify the structure of the container. That's because in the general case, modifying a container can invalidate the iterators being used.
You can modify the element as long as it doesn't change the container's structure (such as the order of elements in the container).
[addition]
Note that there seems to be some confusion about for_each
being a 'non-modifying' algorithm. This confusing situation is summed up here by Stroustrup in errata for the 4rd Printing of "The C++ Programming Language, 3rd Ed." (CPL) has this to say about whether for_each
can modify the elements of a sequence (http://www.research.att.com/~bs/3rd_printing5.html):
"The
for_each()
algorithm is classified as nonmodifying because it doesn't explicitly modify a sequence. However, if applied to a non-const sequencefor_each()
may change the elements of the sequence. For an example, see the use ofnegate()
in 11.9." (recent standards resolution).
The CPL originally indicated that the function or function object passed to for_each
was not permitted to modify the element passed to it. However, the CPL was written and originally published before the standard was finalized, and apparently this restriction on for_each()
was removed before it was finalized.
See also:
See this defect report they say
The LWG believes that nothing in the standard prohibits function objects that modify the sequence elements. The problem is that for_each is in a secion entitled "nonmutating algorithms", and the title may be confusing. A nonnormative note should clarify that.
But also note this one.
They seem to call it "non-modifying" because for_each itself does not exlicitly modify the elements of the sequence.
I think "Non-modifying sequence operations" mean that this operation not modify sequence. But operation could modify container elements.
Value of container elements and sequence - different things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With