Для итераторов, таких как те, которые были возвращены с std::back_inserter()
, есть ли что-то, что можно использовать как итератор «end»?"end()" итератор для вставных вставок?
Это кажется немного бессмысленным сначала, но у меня есть API, который:
template<typename InputIterator, typename OutputIterator>
void foo(
InputIterator input_begin,
InputIterator input_end,
OutputIterator output_begin,
OutputIterator output_end
);
foo
выполняет некоторую операцию на входной последовательности, генерирует выходную последовательность. (Длина Кто сейчас известно foo
, но может или не может быть равна длине входной последовательности в.)
Изъятие параметра output_end
нечетная часть: std::copy
не делает этого, к примеру, и предполагает, что вы» не собираюсь передавать ему мусор. foo
делает это для проверки диапазона: если вы передаете диапазон слишком малым, он выдает исключение во имя защитного программирования. (Вместо потенциальной перезаписи случайных бит в памяти.)
Теперь, скажем, я хочу передать foo
устройство для вставки назад, в частности, одно из std::vector
, которое не имеет ограничений за пределами ограничений памяти. Мне все еще нужен итератор «end» - в этом случае то, что никогда не сравнится с равным. (Или, если у меня был std::vector
, но с ограничением по длине, возможно, он иногда сравнивался бы равным?)
Как мне это сделать? У меня есть возможность изменить API foo
- лучше ли не проверять диапазон, а вместо этого предоставлять альтернативные средства для получения требуемого выходного диапазона? (Что было бы необходимо в любом случае для необработанных массивов, но не обязательно для обратных вставок в вектор.) Это казалось бы менее надежным, но я изо всех сил стараюсь сделать «надежную» (выше) работу.
Это разумный подход. Я не думал проверять, будет ли 'out_it == out_end' на каждой итерации вместо вычисления расстояния. Если алгоритм может быть изменен таким образом, что два выходных итератора могут быть разных типов (с использованием двух параметров шаблона), это можно упростить, просто используя итератор 'back_inserter_end', который при сравнении с любым итератором возвращает не равным. Это сделало бы гораздо меньше кода, но, возможно, более беспорядочным. Я все еще не думаю, что проверка диапазона, как это, отличная идея, но если она действительно желательна, это хороший способ ее достижения! –
@James: Итератор 'back_inserter_end' звучит соблазнительно ... Было бы неплохо, если бы все итераторы имели значение« NULL », например, указатели, так как это значение можно было бы использовать вместо того, чтобы иметь отдельный тип для его хранения. Ну что ж. –
Все это отличные ответы, и я хотел бы отметить «Принятый ответ» более чем на одну вещь. Я поддержал ваши (хотя я бы хотел, чтобы я мог +2), но я даю Джеймсу принятый ответ, так как это решение, с которым я иду. (это будет библиотека, поэтому я не уверен в том, чтобы разоблачить это во внешнем API). Это было определенно информативно и интересно - спасибо, что нашли время, чтобы опубликовать его. – Thanatos