c++c++20boost-hanastd-ranges

Why wrapping call to function returning by value in hana::always circumvent requirements of ranges::views::join? Or maybe it doesn't?


This function, fed with any int, returns a std::vector<int> by value:

auto make = [](int){
    return std::vector<int>{1,2,3};
};

Therefore, such a thing can't work

std::vector<int> v{1,2,3};
auto z = v | std::ranges::views::transform(make)
           | std::ranges::views::join; // fails to compile

because, I understand (but correct me if I'm wrong), when the iterator wrapped in join advances, it triggers the generations of the vectors by means of make, but those temporary are already destroyed by the time the iterator in join is dereferenced.

However, the following doesn't fail:

std::vector<int> v{1,2,3};
auto z = v | std::ranges::views::transform(boost::hana::always(make(int{})))
           | std::ranges::views::join;

Why is that? What mechanism is being introduced by the use of always?

I think the following is proof that both functions, make and always(make(int{})), return a temporary. Am I making a mistake?

static_assert(!std::is_reference_v<decltype(make(int{}))>);
static_assert(!std::is_reference_v<decltype(boost::hana::always(make(int{}))(int{}))>);

Full demo.


Solution

  • There are two separate issues.