最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Why can't a view be assigned with the same type of the view? - Stack Overflow

programmeradmin2浏览0评论

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

Demo:

#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.

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

Demo: https://godbolt./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.

Share Improve this question edited Jan 17 at 20:02 Remy Lebeau 601k36 gold badges508 silver badges851 bronze badges asked Jan 17 at 17:02 Damir TenishevDamir Tenishev 3,4678 silver badges22 bronze badges 10
  • 1 std::ranges::filter_view only has a relevant constructor, not operator= (and auto selected = ... is initialization, not assignment). – wohlstad Commented Jan 17 at 17:06
  • @wohlstad, thank you for pinpointing this. I messed up ranges and views. Of course, it returns view, not a range; my bad. I've updated the question. Nonetheless, the question is still on the table; why can't we (re)assign the views? Is there any reason for that? And I agree with wording, updated the question from (re)assign to assign. – Damir Tenishev Commented Jan 17 at 17:09
  • 7 It's not the same type. Each lambda has a distinct type, and the predicate type is part of the filter_view. – StoryTeller - Unslander Monica Commented Jan 17 at 17:15
  • 3 Please note that those are not the same type: godbolt./z/a1q3PzrM7 – Bob__ Commented Jan 17 at 17:16
  • 3 Also note that this vew can be assigned, when it is assigned the same type. – Drew Dormann Commented Jan 17 at 17:18
 |  Show 5 more comments

1 Answer 1

Reset to default 4

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';
}
发布评论

评论列表(0)

  1. 暂无评论