Closed kirillgrachoff closed 2 years ago
А разве вот этот конструктор не тот, что вы ищете ?
template< class InputIt >
basic_string( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
Да и разве это нормально, чтобы итераторы на основе которых вы создаёте строку имели разный тип, это чисто логически как ? Типо от элемента одного контейнера до элемента другого ? Подумайте, может чего-то просто не поняли и есть способ сделать то, что вы предлагаете по-другому
Нет, это не тот конструктор.
std::ranges::split_view
и другие Ranges могут иметь своим началом и концом итераторы разного типа. Самое главное, чтобы они были сравниваемы.
Попробуйте следующий код:
std::string s = "hello world";
auto v = std::ranges::split_view(s, ' ');
for (auto i : v) {
std::cout << std::is_same_v<decltype(std::ranges::begin(i)), decltype(std::ranges::end(i))> << '\n';
}
Как это логически: хочется за O(1) копировать view
. Но хочется по нему итерироваться. Хочется за O(1) находить конец. Решение - сделать так, чтобы end
возвращал другой тип, который бы дёргал объект и спрашивал, есть ли там следующий.
Кажется предложения для sentinel-ов уже давно есть и что-то уже есть в C++20 experimental. Наверняка и для контейнеров уже всё продумывается.
Про конструирование контейнеров, которое затруднено на самом деле: https://timur.audio/how-to-make-a-container-from-a-c20-range
Комитет решил идти немного другим путём, через ranges::to https://wg21.link/p1206
Приняли в C++23 вместе с новыми конструкторами от диапазона для контейнеров https://wg21.link/p1206
Почему больно без этого
Возьмём код на С++. Вполне обычный код.
Работает.
Теперь вспомним про замечательные Ranges.\ Что теперь хочется?\ А хочется вот так:
Но ни то, ни другое не компилируется т.к. у std::string (и у других контейнеров) нет таких штук.
Предложение
Добавить к каждому std контейнеру хотя бы конструктор от двух итераторов разного типа (это несложно). Всего лишь добавить
Где
Comparable<T, U>
- этоconcept
, отвечающий за то, чтобы их можно было сравнивать друг с другом.