Home > database >  Range-v3: Why is ranges::to_vector needed here?
Range-v3: Why is ranges::to_vector needed here?

Time:10-23

I'm trying to compute a reversed views::partial_sum. The code below gives the expected result of a non-reversed partial_'min', but I need to use ranges::to_vector in order to un-views::reverse the final result (since you can't views::reverse a views::partial_sum). However, when the second to_vector is uncommented, the views::values of intermediate2 are all zeros (although the keys are computed correctly). Uncommenting the first to_vector will fix this, but I'd like to know why? And whether I it is possible to avoid the first to_vector? Or whether should I just not bother with understanding and just chuck in to_vectors until the code works.

    auto input = std::vector<float>{} | actions::push_back(views::iota(0u, COUNT)) | actions::shuffle(std::default_random_engine{});;

    auto intermediate1 = views::zip(views::iota(0u, COUNT), input)
        //| to_vector
        ;
    auto intermediate2 = intermediate1
        | views::reverse
        | views::partial_sum(
            [](std::pair<unsigned, float> a, std::pair<unsigned, float> b)
            {
                if (a.second > b.second)
                    return b;
                else
                    return a;
            })
        //| to_vector
        ;
    auto ans = intermediate2
        //| views::reverse
        ;

    std::cout << "values  = " << (ans | ranges::views::values | views::take(23)) << std::endl;
    std::cout << "indices = " << (ans | ranges::views::keys | views::take(23)) << std::endl;

EDIT I overlooked that the uncommenting the final reverse breaks the code again, even with both to_vectors so it must a problem with reverse as per Barry's answer.

CodePudding user response:

This is a range-v3 bug that is a result of views::reverse not properly propagating the value_type, and so you end up with a vector<common_pair<unsigned int, float&>> (note the reference) where you should really be ending up with a vector<pair<unsigned int, float>>. This will be fixed by this PR.

In the meantime, you can fix this yourself by providing an explicit type for the vector that you're converting into, via ranges::to<std::vector<std::pair<unsigned int, float>>>().

  • Related