3

I know transform algorithm in C++ is a mutating sequence algorithm. But I have never seen anyone using transform for the purpose of mutating a sequence. Whenever I search for a sample code on internet, what I get is the transform algorithm used similar to for_each algorithm.

Please provide a link or an example , where I can understand the mutating sequence nature.

Edit: I got more confused when I went through This SO question. it says for_each is a non-modifying sequence algorithm. So I can modify the elements with for_each not the structure of the container.Is the provided answer incorrect. If for_each can also modify the element, we can replace for_each with transform,and there is no need of for_each algorithm except that it's implementation may be simple.

Community
  • 1
  • 1
Sreeraj Chundayil
  • 5,548
  • 3
  • 29
  • 68

2 Answers2

4

mutating sequence algorithm means algorithm will change (modify) the container it works on. In example below, the container foo of type std::vector is modified.

std::string s("hello");
std::vector<int> foo;
std::transform(s.begin(), s.end(), back_inserter(foo), ::toupper);
std::cout << std::string(foo.begin(), foo.end());

The output is "HELLO"

This is not possible with std::for_each


Yes that provided answer sounds correct to me. Also check the list of Nonmodifying Sequence Algorithms and Mutating Sequence Algorithms in C++ to verify your assertions.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
2

Here is a simple example

#include <iostream>
#include <algorithm>
#include <iterator>

int main() 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    std::transform( std::begin( a ), std::end( a ), std::begin( a ),
                    []( int x ) { return x * x; } );

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

The output is

1 2 3 4 5 6 7 8 9 10 
1 4 9 16 25 36 49 64 81 100 

The same can be done using algorithm std::for_each

#include <iostream>
#include <algorithm>
#include <iterator>

int main() 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    std::for_each( std::begin( a ), std::end( a ),
                   []( int &x ) { x = x * x; } );

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

Though std::for_each is referred as a non-mutable algorithm nevertheless in its description there is written

2 Effects: Applies f to the result of dereferencing every iterator in the range [first,last), starting from first and proceeding to last - 1. [ Note: If the type of first satisfies the requirements of a mutable iterator, f may apply nonconstant functions through the dereferenced iterator.β€”end note ]

So in fact it can be used as a mutable algorithm.

Both algorithms, std::for_each and std::transform, belong to the category of non-modifying sequence operations becuase they do not change the order of elements of the source sequence..

It seems you mix two notions: mutable algorithms and non-modifying sequence alforithms.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335