1

I'm learning the ranges-v3 library and have a problem with compiling the following code:

#include <range/v3/all.hpp>
#include <iostream>
#include <vector>

using namespace ranges;
using std::vector;
using std::pair;

// does not use ranges in my actual code
vector<float> render(unsigned width, unsigned i) {
    std::mt19937 gen(i);
    std::uniform_real_distribution<float> dis(0.f, 1.f);
    return to_vector(view::generate_n(
                         [&gen, &dis](){ return dis(gen); },
                         width));
}

int main()
{
    unsigned n = 2;
    unsigned width = 3;

    auto sq = [](auto v) { return v * v; };
    auto addPairs = [](auto a, auto b) {
        return std::make_pair(a.first + b.first, a.second + b.second);
    };
    auto addPairVectors = [addPairs](auto rA, auto rB) {
        return view::zip_with(addPairs, rA, rB);
    };
    auto valueError = [sq](float i, float ref) {
        return std::make_pair(i, sq(i - ref));
    };


    vector<float> reference(width, 0.5f);

    auto renderData =
            view::iota(0u, n)
/*line 39*/ | view::transform([width](auto i) { return render(width, i); })
            | view::join;

    auto referenceRepeated =
            view::repeat(reference)
            | view::join;

    auto renderDataWithError =
/*line 47*/ view::zip_with(valueError, renderData, referenceRepeated)
            | view::chunk(width);

    auto nTimesResultAndError = accumulate(renderDataWithError,
                                           vector<pair<float, float>>(width),
                                           addPairVectors);

    float nInv = 1.f/n;
    auto result = to_vector(
                nTimesResultAndError
                | view::transform([nInv](auto v) { return v.first * nInv;}) );
    auto stdDev = to_vector(
                nTimesResultAndError
                | view::transform([nInv](auto v) {
                                      return std::sqrt(v.second * nInv);
                                  }));

    return 0;
}

g++ says:

../rangesTest/main.cpp:47:69:   required from here
../rangesTest/include/range/v3/view/all.hpp:78:35:
error: static assertion failed: Cannot get a view of a temporary container

I've tried g++7 and 8 and clang 6. All of them say something similar. My understanding is that the problem is on line 39, where i return the temporary.

My goal here is to compute the renderings only one at a time and add them one by one to the sum. Apparently that does not work with the code above. Is it at all possible to formulate that with the ranges library and how?

Barry
  • 286,269
  • 29
  • 621
  • 977
Adam
  • 488
  • 4
  • 17
  • Specifically, see Casey's answer about the `store()` function – Barry Dec 17 '18 at 20:46
  • I'm already reading it (somehow i missed it while looking for other answers). But no luck yet with the solution. – Adam Dec 17 '18 at 20:56
  • I tried to use the solution with store, it compiles but aSan shows me a heap-use-after-free error now (see the edit). – Adam Dec 17 '18 at 21:28
  • Please don't edit answers into questions, or change the substance of questions like this - just ask a new question. I rolled back your edits. – Barry Dec 17 '18 at 21:33

0 Answers0