Damir Tenishev
Damir Tenishev

Reputation: 3402

Why can't a view be assigned with the same type of the view?

Why can't I (re)assign the value for a view with the same type of the view?

Demo: https://godbolt.org/z/aqdh7ohva

#include <iostream>
#include <ranges>
#include <vector>

int main()
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6 };

    const bool strategy_check_for_zero = true;

    auto selected = v | std::views::filter([=](const auto& v) { return !strategy_check_for_zero || v != 0; });

    // Impossible to do; why?
    selected = v | std::views::filter([=](const auto& v) { return true; });

    std::ranges::copy(selected, std::ostream_iterator<int>{std::cout, ", "});
    std::cout << '\n';
}

Well, in real code, it is more like this:

auto selected = v | std::views::filter([=](const auto& v) { return !strategy_check_for_zero || v != 0; });

if (selected.empty()) {
    selected = v | std::views::filter([=](const auto& v) { return true; });
}

I want to keep the code in question as simple as possible.

Upvotes: 0

Views: 87

Answers (1)

Drew Dormann
Drew Dormann

Reputation: 63947

Why I can't (re)assign the value for a view even with the same type of the view?

Simple. It's not the same type.

Chaining views together produces a distinct type for the requested view.

If the view actually is the same type, your code will compile.

#include <iostream>
#include <ranges>
#include <vector>

int main()
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6 };

    const bool strategy_check_for_zero = true;

    auto lambda = [=](const auto& v) { return !strategy_check_for_zero || v != 0; };
    
    auto selected = v | std::views::filter(lambda);
    selected = v | std::views::filter(lambda);

    std::ranges::copy(selected, std::ostream_iterator<int>{std::cout, ", "});
    std::cout << '\n';
}

Upvotes: 4

Related Questions