range-v3: соединение трубопроводов с разделителем - PullRequest
2 голосов
/ 28 марта 2019

Я пытаюсь создать базовую демонстрацию библиотеки range-v3: взять несколько целых чисел, отфильтровать нечетные значения, зачеркнуть их, а затем объединить их в список через запятую.Например, { 8, 6, 7, 5, 3, 0, 9 } становится "8, 6, 0".После прочтения документов и изучения примеров кажется, что наивное решение будет выглядеть так:

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(", ");
}

, но сборка на Clang 7 терпит неудачу со статическим утверждением, что "Не удается получитьвид временного контейнера ".Поскольку я собираю результат в строку, я могу использовать вместо этого нетерпеливую версию - action::join -:

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;
}

, но в нетерпеливой версии, похоже, нет перегрузки, которая принимает разделитель.

Интересно, что исходное утверждение исчезнет, ​​если вы сначала соберете входные данные join в контейнер.Следующее компилируется и работает нормально:

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(", ");
}

, но это полностью противоречит принципу ленивых вычислений, который управляет такой большой частью библиотеки.

Почему первый пример дает сбой?Если это невозможно, можно ли дать action::join разделитель?

1 Ответ

3 голосов
/ 28 марта 2019

action::join следует принять разделитель. Не стесняйтесь подать запрос на функцию. Действиям нужно много любви.

...