3

I'm trying to build a basic demo of the range-v3 library: take some integers, filter out odd values, stringify them, then join those into a comma-separated list. For example, { 8, 6, 7, 5, 3, 0, 9 } becomes "8, 6, 0". From reading the docs and going through examples, it seems like the naïve solution would resemble:

string demo(const vector<int>& v)
{
    return v |
        ranges::view::filter([](int i) { return i % 2 == 0; }) |
        ranges::view::transform([](int i) { return to_string(i); }) |
        ranges::view::join(", ");
}

but building on Clang 7 fails with a static assertion that one, "Cannot get a view of a temporary container". Since I'm collecting the result into a string, I can use the eager version - action::join - instead:

string demo(const vector<int>& v)
{
    return v |
        ranges::view::filter([](int i) { return i % 2 == 0; }) |
        ranges::view::transform([](int i) { return to_string(i); }) |
        ranges::action::join;
}

but the eager version doesn't seem to have an overload that takes a delimiter.

Interestingly, the original assertion goes away if you collect join's inputs into a container first. The following compiles and runs fine:

string demo(const vector<int>& v)
{
    vector<string> strings = v |
        ranges::view::filter([](int i) { return i % 2 == 0; }) |
        ranges::view::transform([](int i) { return to_string(i); });
    return strings | ranges::view::join(", ");
}

but this totally defeats the principle of lazy evaluation that drives so much of the library.

Why is the first example failing? If it's not feasible, can action::join be given a delimiter?

Matt Kline
  • 10,149
  • 7
  • 50
  • 87
  • At first glance this question resembles https://stackoverflow.com/q/48383671, but there seems to be different problems at play there. `ranges::to_` doesn't solve this problem. – Matt Kline Mar 27 '19 at 21:13
  • Why don't you return auto instead of string? This will allow you to make it truly lazy – bartop Mar 27 '19 at 22:08
  • You certainly would outside a demo like this, but that just makes the static assertion occur elsewhere. Eventually you want to collect the result into a string (for I/O or storage in another structure), and it fires there. – Matt Kline Mar 27 '19 at 23:03

1 Answers1

4

action::join should accept a delimiter. Feel free to file a feature request. The actions need a lot of love.

Eric Niebler
  • 5,927
  • 2
  • 29
  • 43