STL-reverse_iterator обратный итератор

обзор

Для контейнера в STL очень важной частью является итератор (итератор).В то же время итератор также является одним из шести основных компонентов STL.В предыдущей реализации вектора и списка у нас уже был предварительный понимание итераторов Зачем проектировать итератор? Просто чтобы иметь возможность проходить данные через ++, -- операции вроде указателей в массиве .

Например, вектор сам по себе является массивом на нижнем уровне, строкой непрерывных данных, а его итератор — необработанным указателем.

И список, это не непрерывное хранилище, но вы можете найти следующий узел (данные) через указатель _next каждого узла, а его итератор - это класс, нижний член класса - это указатель узла, а затем перегрузите + +,--, вы можете перемещаться по данным как по вектору.

обратный итератор (reverse_iterator)

Обратный итератор — это обратный обход итератора (forward iterator) , обход от хвоста к голове, что несложно понять.

Прямой итератор, как мы знаем, — это интервал, закрытый слева и открытый справа, так что же это за интервал, который является обратным итератором?

Давайте пока отложим этот вопрос в сторону, и каждый может подумать над ним некоторое время.

Если мы хотим реализовать обратный итератор, нужно ли нам писать реализацию обратного итератора? Будет ли это существенно похоже на код нашей реализации прямого итератора? Для STL слишком много повторяющегося кода будет выглядеть раздутым и расточительным, так как же STL реализует обратные итераторы?

Для реализации обратного итератора STL использует метод адаптера для инкапсуляции прямого итератора. А для адаптеров мы уже знаем о стеке, очереди и т.д. Итак, обратные итераторы, не просто итераторы, а адаптеры!

Где обратные итераторы подходят в качестве адаптеров? STL позволяет контейнерам, поддерживающим обход в обратном порядке, адаптировать свои прямые итераторы к соответствующим обратным итераторам!

template<typename Iterator , typename Ref, typename Ptr>
	struct __reverse_iterator {
		typedef __reverse_iterator<Iterator, Ref, Ptr> RIterator;

		Iterator _data;    //成员变量

        __reverse_iterator(Iterator it)
			:_data(it)
		{}

	};

Первый параметр шаблона здесь — это прямой итератор, который вам нужно адаптировать, а второй и третий параметры согласуются с прямым итератором, который используется для определения и оценки того, является ли ваш итератор константным.

Как пройти задним ходом? Он просто заменяет операцию ++ прямого итератора на операцию --!

RIterator& operator++()
{
	--_data;
	return *this;
}

RIterator operator++(int)
{
	__reverse_iterator tmp(_data);
	--_data;
	return tmp;
}

RIterator& operator--()
{
	++_data;
	return *this;
}

RIterator operator--(int)
{
	__reverse_iterator tmp(_data);
	++_data;
	return tmp;
}

диапазон обратного итератора

Теперь, когда вы знаете, как работает обратный итератор, есть ли у вас предположения о диапазоне его обхода?

STL устроен так

 Возьмите вектор в качестве примера

Ref operator*()
{
	Iterator tmp = _data;
	return *(--tmp);
}

Ptr operator->()    //针对自定义类型指针访问成员
{
	return &(operator*());
}

bool operator!=(const RIterator& it)
{
	return _data != it._data;
}

RIterator rbegin()
{
	return RIterator(end());
}

const_RIterator rbegin() const
{
	return RIterator(end());
}

RIterator rend()
{
	return RIterator(begin());
}

const_RIterator rend() const
{
	return RIterator(begin());
}

И обход обратного итератора такой

vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(3);
v1.push_back(3);
v1.push_back(6);
v1.push_back(4);
vector<int>::RIterator Rit = v1.rbegin();
while (Rit != v1.rend())
{
	cout << *Rit << " ";
	++Rit;
}
cout << endl;

Обратный итератор — это не просто итератор, а адаптер. Написание обратного итератора может принести пользу многим контейнерам. Почему многим, а не всем? Потому что итераторы некоторых контейнеров не поддерживают операцию --, например односвязные списки, которые не поддерживают обход в обратном порядке.

рекомендация

отblog.csdn.net/fengjunziya/article/details/130884296