Я пытаюсь понять, как могут быть составлены представления, и их ограничения.
Идея здесь состоит в том, чтобы разделить string
/string_view
без создания временной переменной, как показано во втором блоке кода.
Почему не компилируется следующее:
std::string line = "1[2]3";
for (const auto split : line
| std::ranges::views::split('[')
| std::ranges::views::transform([](const auto rng) {return std::string_view(rng); })
| std::ranges::views::split(']')
| std::ranges::views::transform([](const auto rng) {return std::string_view(rng); })) {
std::cout << split << '\n';
}
Дополнительный вопрос: почему приведенный выше код не компилируется, но работает следующее:
for (const auto split_once : line
| std::ranges::views::split('[')
| std::ranges::views::transform([](const auto rng) {return std::string_view(rng); })) {
for (const auto split_twice : split_once
| std::ranges::views::split(']')
| std::ranges::views::transform([](const auto rng) {return std::string_view(rng); })) {
std::cout << split_twice << '\n';
}
}
@TedLyngmo спасибо, что указали на опечатку. Сообщение об ошибке довольно длинное; на случай, если вы пропустили это, есть ссылка на проводник компилятора, где видна ошибка.
Первый views::transform
создает диапазон, элементы которого имеют тип string_view
, который невозможно просто разделить символом ']'
.
Вместо этого вы можете, например, продолжать разделять каждую string_view
и объединять их вместе.
std::string line = "1[2]3";
for (const auto split : line
| std::ranges::views::split('[')
| std::ranges::views::transform(
std::ranges::views::split(']') |
std::ranges::views::transform(
[](auto rng) {return std::string_view(rng); })
)
| std::views::join) {
std::cout << split << '\n';
}
std::views
— это сокращение от std::ranges::views
. Вы можете пойти еще дальше и внедрить пространство имен в используемую область (непосредственно перед циклом for
):{using namespace std::views; for/*...*/};
. Фигурные скобки ограничивают видимость пространства имен и минимизируют вероятность конфликта имен, одновременно приводя к более сжатому коду.
Спасибо за ваш ответ! Не могли бы вы расширить ответ, чтобы объяснить, почему второй блок кода в вопросе работает, когда выходные данные transform
передаются по конвейеру в split
, но сначала сохраняются как именованная переменная? Кроме того, что касается вашего ответа, почему вторая split
работает, когда вызывается внутри transform
, но не снаружи (т. е. как функция transform
изменяет/влияет на входные данные, чтобы вторая split
работала правильно)?
@vss2sn Потому что тип split_once
— это string_view
, который можно разделить одним символом ']'
.
В первом, похоже, нет ни сбалансированных
{
и}
, ни сбалансированных(
и)
. Включите сообщение об ошибке в вопрос.