Код: Выделить всё
(bool)Itterator
Код: Выделить всё
Itterator!=Contaner.End()
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Код: Выделить всё
(bool)Itterator
Код: Выделить всё
Itterator!=Contaner.End()
Не понял, поясните. В чём собственно проблема?Не каждый итератор может сам по себе определить, что перебор контейнера завершён. Итератор списка, как в твоём случае, может. А вот, например итератор вектора не знает, принадлежит ли следующая лежащая в памяти ячейка контейнеру или нет, поэтому без контейнера это определить не получится.
Код: Выделить всё
class TArray
{
private:
int *Items;
size_t Count;
public:
Itterator Begin()
{
return Itterator(Items, Items+Count-1);
}
class Itterator
{
friend class TArray
private:
int *Last;
int *Current;
Itterator (const int *Current, const int *Last)
{
this->Current=Current;
this->Last=Last;
}
public:
Itterator ()
{
Current=nullptr;
Last=nullptr;
}
Itterator oparator ++ ()
{
if ((Current!=nullptr)&&(Last!=nullptr))
{
++Current;
if (Current>Last)
{
Current=nullptr;
}
}
}
};
И в чём проблема перегрузить оператор "унарный *"?Romeo писал(а):Проблема в том, что итератор по факту должен быть некой обёрткой над поинтером, который указывает на данные и, более того, притворятся эти поинтером, то есть иметь такой же интерфейс.
И каким же образом могут быть универсальны внутренности иттератора? Их классы не просто так являются членами классов контейнеров вместо единого класса иттератора "вперёд" и одного реверсивного.Любые усложнения нарушают концепцию универсальности,
А это то здесь при чём?Зачем нужна универсальность интерфейса итератора?
Ну ка переберите список указателем, юзая простой инкремент вместо p=p->Next. Они ведь не знают не только о конце контейнера, но и о фактическом размещении следующего элемента.Она позволяет обобщённым алгоритмам из <algorithm> работать одинаково как с итераторами, так и с обычными указателями, которые конечно же не имеют никаких дополнительных знаний о контейнерах.
Код: Выделить всё
std::unique_ptr<Foo> p = getPooPtr();
if (p) {
// p is valid
}
Смарт-указатель может учитывать все что угодно. std::unique_ptr, например, позволяет учитывать заданные пользователем способы удаления объекта.Но итератор есть указатель, учитывающий структуру контейнера и фактическое размещение в памяти следующего элемента.
В корне не согласен. Итераторы и смарт-поинтеры похожи только тем, что прячут в себе указатель. Но по ни по функциональному предназначению, ни по имплементационым требованиям они вообще не сравнимы.Absurd писал(а):Итератор это разновидность смарт-указателя.
В текущей реализации STL у итератора нет оператора bool. И, кстати, это объясняется достаточно просто. Если для итераторов одних контейнеров, таких, как список, нулевое значение внутреннего указателя может сигнализировать об окончании перебора, то для других, скажем, вектора, окончание перебора вообще не может быть определено без дополнительной информации, так как итерирование, по факту, идёт по диапазону адресов, и где заканчивается этот диапазон "знает" только контейнер.Absurd писал(а):У смарт-указателей operator bool() обычно перегружают, чтобы работало такое.
Речь идёт об универсальности интерфейса, а не внутренностей. Дело в том, что все алгоритмы реализованы в виде внешних шаблонных функций, так что они не привязаны к типу итератора. Можно передать как обычные поинтеры, так и объекты своего класса. Главное, чтоб был доступен весь набор необходимых операторов, чтобы компилятор смог сгенерировать инстанс функции для этого типа.Сионист писал(а):И каким же образом могут быть универсальны внутренности иттератора? Их классы не просто так являются членами классов контейнеров вместо единого класса иттератора "вперёд" и одного реверсивного.
Ну почему ты любую идею пытаешь извратить? Смотри, давай по порядку.Сионист писал(а):Ну-ка переберите список указателем, юзая простой инкремент вместо p=p->Next. Они ведь не знают не только о конце контейнера, но и о фактическом размещении следующего элемента.
Код: Выделить всё
const int N = 3;
int arr[N] = {1, 2, 3};
...
int* begin = arr;
int* end = arr + N;
for (int* p = begin; p != end; ++p)
{
printf("%d ", *p);
}
Ну не знаю. По моему все типы с перегруженными * и -> входят в множество обобщенных указателей. А обобщенные указатели это тоже самое что и смарт-указатели.Итераторы и смарт-поинтеры похожи только тем, что прячут в себе указатель. Но по ни по функциональному предназначению, ни по имплементационым требованиям они вообще не сравнимы.
Ну это понятно что каноничный способ сравнения это сравнение с end(). Но ничто не мешает этот bool реализовать при желании.В текущей реализации STL у итератора нет оператора bool.