Я обнаружил, что c++20 ranges::basic_istream_view
немного отличается от range-v3.
Самое важное отличие состоит в том, что std::ranges::basic_istream_view
не кэширует свой begin()
, так что каждый begin()
будет возвращать следующий итератор со значением, которое было прочитано (богболт):
auto words = std::istringstream{"today is yesterday's tomorrow"};
auto view = std::ranges::istream_view<std::string>(words);
std::cout << *view.begin() << "\n"; // today
std::cout << *view.begin() << "\n"; // is
std::cout << *view.begin() << "\n"; // yesterday's
std::cout << *view.begin() << "\n"; // tomorrow
Рассмотрим следующее (godbolt). Если я использую версию range-v3, все три std::ranges::find()
будут найдены "is"
, но если я использую стандартную версию, "is"
будет найден только при первом вызове.
auto words = std::istringstream{"today is yesterday's tomorrow"};
auto view = std::ranges::istream_view<std::string>(words);
std::cout << *std::ranges::find(view, "is") << "\n"; // is
std::cout << *std::ranges::find(view, "is") << "\n"; // tomorrow
std::cout << *std::ranges::find(view, "is") << "\n"; // tomorrow
Почему стандарт выбрал дизайн, отличный от range-v3? Есть ли потенциальный дефект, если begin()
кэшируется?