C++ для каждого в пользовательских коллекциях
Так как он был представлен, я любил for each
в ключевых словах, чтобы повторить STL collections
Я очень большой поклонник синтаксического сахара.
У меня вопрос, как я могу написать собственную коллекцию, которую можно повторять, используя эти ключевые слова?
По сути, какой APi мне нужно предоставить, чтобы мои коллекции были повторяемыми с использованием этих ключевых слов?
Я прошу прощения, если это звучит тупо, но, пожалуйста, не отвечайте "используйте повышение", "не пишите свои собственные коллекции" или тому подобное. Погоня за знаниями, друзья мои. Если это невозможно, эй, я справлюсь с этим.
Я также очень предпочел бы не вводить итератор STL в мои коллекции.
Заранее спасибо!
2 ответа
Вот хорошее объяснение повторяющихся структур данных ( циклы на основе диапазона):
Чтобы сделать структуру данных итеративной, она должна работать аналогично существующим итераторам STL.
- Должно быть
begin
а такжеend
методы, которые работают с этой структурой, либо как члены, либо как автономные функции, и которые возвращают итераторы в начало и конец структуры. - Сам итератор должен поддерживать
operator*
метод,operator !=
метод иoperator++
метод, либо как члены, либо как отдельные функции.
Обратите внимание, в C++11
есть встроенная поддержка циклов на основе диапазона без использования STL
хотя вышеупомянутые условия справедливы и для этого. Вы можете прочитать об этом по той же ссылке выше.
Из твоего вопроса не совсем понятно, говоришь ли ты о std::for_each
определены в <algorithm>
заголовок или цикл, основанный на диапазоне, введенный в C++11.
Тем не менее, ответ одинаков для обоих.
Оба работают на итераторах, а не на самой коллекции.
Так что вам нужно
определить тип итератора, который удовлетворяет требованиям, предъявляемым к нему STL (действительно, стандарт C++). (Главное, что он должен определить
operator++
а такжеoperator*
и пару других операций и typedefs)за
std::for_each
Мало 2. Готово. Вы просто передаете два таких итератораstd::for_each
, Для цикла for, основанного на диапазоне, вам нужно выставить пару этих итераторов черезbegin()
а такжеend()
функции.
И это все.
Единственная сложность - создание итератора, соответствующего требованиям. Boost (даже если вы сказали, что не хотите его использовать) имеет библиотеку, которая помогает в реализации пользовательских итераторов (Boost.Iterator). Также есть std::iterator
класс, который предназначен в качестве базового класса для пользовательских реализаций итераторов. Но ни то, ни другое не нужно. Оба являются просто удобными инструментами, чтобы упростить создание собственного итератора.