Open kelbon opened 2 years ago
Если нужно чтобы диапазон завладел контейнером можно воспользоваться std::ranges::owning_view:
for (auto v : views::owning_view{make_generator()})
std::cout << v;
И работает без специализации enable_borrowed_range. Или вам нужно что-то другое?
Если нужно чтобы диапазон завладел контейнером можно воспользоваться std::ranges::owning_view:
for (auto v : views::owning_view{make_generator()}) std::cout << v;
И работает без специализации enable_borrowed_range. Или вам нужно что-то другое?
- тот кто использует генератор вполне может об этом не знать или забыть.
- This specialization of std::ranges::enable_borrowed_range makes owning_view satisfy borrowed_range when the underlying range satisfies it. Что означает, что будет ошибка компиляции в выражении из примера(в вашем примере всё будет хорошо в любом случае, даже без ренжей). Потому что сейчас генератор нельзя сделать borrowed_range по вот такой вот причине с begin&&
Если в случае range based for loop игнорировать такие перегрузки ещё адекватно, то в случае ranges это приводит к проблемам, например, пусть у меня есть условный генератор - корутина, тогда в в случае && для интеграции с std::ranges я бы мог перегрузить begin для &&,, создав владеющий итератор(владеющий coroutine_handle) При этом метод end() является статическим, поэтому никаких проблем с вызовом end после вызова перегруженного для && метода нет.
Тогда пользователь мог бы безопасно писать
Сейчас произойдёт UB, т.к. внутри ranges не происходит forward ренжа, и выберется не та перегрузка begin, скорее всего рантайм ошибка(в лучшем случае)
Как я предлагаю это исправить: Исправить текст стандарта
https://eel.is/c++draft/range.subrange#ctor-6.2 https://eel.is/c++draft/range.subrange#access-10 Добавив
std::forward<decltype(r)>
Либо добавить перегрузки с requires, если будет страшно за abi