bendervader bendervader - 7 months ago 71
C++ Question

What is the difference std::transform and std::for_each?

Both can be used to apply a function to a range of elements.

On a high level:

  • std::for_each
    ignores the return value of the function, and
    guarantees order of execution.

  • std::transform
    assigns the return value to the iterator, and does
    not guarantee the order of execution.

When do you prefer using the one versus the other? Are there any subtle caveats?


std::transform is the same as map. The idea is to apply a function to each element in between the two iterators and obtain a different container composed of elements resulting from the application of such a function. You may want to use it for, e.g., projecting an object's data member into a new container. In the following, std::transform is used to transform a container of std::strings in a container of std::size_ts.

std::vector<std::string> names = {"hi", "test", "foo"};
std::vector<std::size_t> name_sizes;

std::transform(names.begin(), names.end(), std::back_inserter(name_sizes), [](std::string name) { return name.size();});

On the other hand, you execute std::for_each for the sole side effects. In other words, std::for_each closely resembles a plain range-based for loop.

Back to the string example:

std::for_each(name_sizes.begin(), name_sizes.end(), [](std::size_t name_size) {
    std::cout << name_size << std::endl;

Indeed, starting from C++11 the same can be achieved with a terser notation using range-based for loops:

for (std::size_t name_size: name_sizes) {
    std::cout << name_size << std::endl;