Я пытаюсь создать базовую демонстрацию библиотеки 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
разделитель?
ranges::to_<string>
не решает эту проблему. - person Matt Kline   schedule 28.03.2019