Мне трудно увидеть практическую разницу между std::fill_n и std::ranges::fill_n.
Даже если нет никакой значимой разницы, кроме более строгой проверки концепции, суть в том, что std::ranges должны иметь альтернативы для всех алгоритмов, чтобы вам больше не приходилось прикасаться к старым.





Есть несколько основных отличий, которые применимы ко всем алгоритмам std и std::ranges:
Те, кто в std::ranges, ограничены в концепциях, поэтому гораздо строже в том, что они принимают. При переносе кода с использованием пользовательских итераторов часто бывает, что итератор не совсем input_iterator (обычно из-за отсутствия чего-то вроде difference_type), поэтому его необходимо обновить. Те, что в std::ranges, также основаны на концепциях итераторов C++20, а не на C++98, поэтому там тоже есть небольшие различия (в первую очередь то, что вам разрешено иметь прямой или лучший итератор, который дает вам значения prvalues) .
Те, что в std::ranges, являются объектами функций, а не шаблонами функций. Технически это «ниблоиды» , но единственный способ реализовать их для получения требуемого стандартного поведения — это использовать их как функциональные объекты, и вполне вероятно, что вскоре они будут определены как таковые.
Многие алгоритмы имеют дополнительные отличия, в частности, они принимают диапазон, а не пару итераторов. Многие из них также имеют аргументы проекции в дополнение к вызываемым объектам. Многие из них также имеют тип возврата, отличный от их аналога std::.
Но fill_n конкретно не имеет этих дополнительных перегрузок или аргументов или имеет отдельный тип возвращаемого значения — std::ranges::fill_n то же самое, что и std::fill_n, за исключением различий, которые я изложил ранее. Вы можете думать о существовании std::ranges::fill_n прежде всего для того, чтобы у каждого std::meow был аналог std::ranges::meow, чтобы вы могли полностью перейти на std::ranges, не думая об этом.
Беглое исследование заставляет меня поверить, что std::fill_n(args...) правильно сформирован, если и только если ограничения std::ranges::fill_n(args...) совпадают, но я могу упустить одну тонкость.
@Caleth Нет. Например, output_iterator не требует тега категории итератора, а Cpp17OutputIterator — требует.
Я бы предпочел использовать ranges::fill на views::take. По крайней мере, это дает минимальную гарантию того, что границы не закончатся. Все алгоритмы на основе итераторов подвержены выходу за пределы UB. ranges::copy – еще одно разочарование; пункт назначения может быть просто захвачен; использование for на основе views::zip(src,dst) на основе диапазона намного безопаснее.
@Red.Wave Это вопрос о разнице между std::fill_n и std::ranges::fill_n.
Ответом является всего лишь вопрос: никакой практической разницы. Безопасность — мое дополнительное требование.
@Red.Wave Эти комментарии не имеют отношения к теме. Вы можете выразить свои требования в другом месте.
Многие стандартные алгоритмы имеют аналогичный
rangesаналог.