简体   繁体   中英

Range-v3: Why is ranges::to_vector needed here?

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_vector s 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;

This is specifically a problem with views::parital_sum as modifying the comments as follows

        //| 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

will give me the expected result.

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>>>() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM