10
#include <vector>
#include <algorithm>
#include <range/v3/all.hpp>

using namespace ranges;

int main()
{
    auto coll = std::vector{ 1, 2, 3 };
    std::for_each(coll.begin(), coll.end(), [](auto){}); // ok
    coll | view::for_each([](auto){}); // static_assert failure
}

The static_assert error message:

To use view::for_each, the function F must return a model of the InputRange concept.

std::for_each takes a functor which returns void, why does ranges::view::for_each require the functor must return a model of the InputRange concept?

llllllllll
  • 16,169
  • 4
  • 31
  • 54
xmllmx
  • 39,765
  • 26
  • 162
  • 323

1 Answers1

12

You misunderstand what view::for_each() is, it's totally different from std::for_each.

The functor in view::for_each() should return another range, then the final effect is that all the ranges are flattened to a big range.

For example:

auto res = coll | view::for_each([](auto n){ return yield_from(view::ints(0, n)); });

The returned range for every element is {0}, {0, 1}, {0, 1, 2} respectively. The res will be the flattened one: {0, 0, 1, 0, 1, 2}

The counterpart of std::for_each is ranges::for_each:

ranges::for_each(coll, [] (auto) {})
llllllllll
  • 16,169
  • 4
  • 31
  • 54
  • 1
    **"You misunderstand what view::for_each() is, it's totally different from std::for_each."** people should emphasize more on that. – gonidelis Nov 16 '21 at 14:38
  • If it gets included in C++23 Ranges, it'll be called `views::flat_map`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2214r1.html#flat_map – underscore_d Dec 31 '21 at 11:49