ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.11k stars 440 forks source link

transform is call twice for each element in range in case of combination with filter #1613

Open sepcon opened 3 years ago

sepcon commented 3 years ago

I have a sample: ` using namespace ranges; namespace rv = ranges::views;

vector<int> vec = { 1, 2, 3 };

auto output = vec
    | rv::transform([](int i) {
    cout << "transform: " << i << endl;
    return i + 1;
        }) | rv::filter([](int i) {
            cout << "filter0: " << i << endl;
            return i > 0;
            });

        for (auto r : output) {
            cout << r << endl;
        }`

The output is: transform: 1 filter0: 2 transform: 1 2 transform: 2 filter0: 3 transform: 2 3 transform: 3 filter0: 4 transform: 3 4

  1. From output we can see: transform: is printed twice for each value --> this should be considered as BUG, right?
  2. If apply filter before transform then transform is applied only once: filter0: 1 transform: 1 2 filter0: 2 transform: 2 3 filter0: 3 transform: 3 4
JohelEGP commented 3 years ago

It isn't a bug. Search for twice and you get similar issues: https://github.com/ericniebler/range-v3/issues?q=twice.

sv1990 commented 3 years ago

There is ranges::views::cache1 to prevent calling the transform function twice.