Перегрузка оператора + для итератора на C++ с исключением out_of_range
Необходимо реализовать перегрузку оператора + для собственного итератора класса. Проблема в выкидывании ошибки, если мы уйдём за границу итератора. Вот код:
class MatrixRow
{
private:
size_t __size;
double* __data;
public:
class Iterator : std::iterator<std::input_iterator_tag, double>
{
private:
double* __curent;
public:
Iterator(double* first) : __current(first) {}
Iterator(const Iterator& ref_iterator) : __current(ref_iterator.__current) {}
double& operator + (int n)
{
if(__curent + n > __data + __size) //Здесь ошибка
{
throw std::out_of_range("Index out of range");
}
return *(__current + n);
}
}
Iterator begin()
{
return Iterator(__data);
}
Iterator end()
{
return Iterator(__data);
}
}
Ответы (2 шт):
Да что ж вы то __current, то __curent пишете, да еще и используете имя с двумя подчерками впереди...
Но в данном случае это к делу не относится. Проблема в том, что __current — член Iterator, а __data и __size — члены совсем другого класса (пусть даже охватывающего), и как получить к ним доступ (грубо — где указан объект, которому они принадлежат?), компилятор не знает.
Вложенность класса не означает какую-либо связь объектов. Объект итератора должен быть связан с объектом контейнера, если он для него пишется.
Кстати, VC++ выдает вот такое предупреждение:
warning C4996: 'std::iterator<std::input_iterator_tag,double,ptrdiff_t,double *,double &>': warning STL4015: The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. (The header is NOT deprecated.) The C++ Standard has never required user-defined iterators to derive from std::iterator. To fix this warning, stop deriving from std::iterator and start providing publicly accessible typedefs named iterator_category, value_type, difference_type, pointer, and reference. Note that value_type is required to be non-const, even for constant iterators. You can define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
но оно в полной мере ни при чем, просто для информации.
Идея Harry:
class MatrixRow
{
private:
size_t __size;
double* __data;
public:
class Iterator : std::iterator<std::input_iterator_tag, double>
{
private:
double* __current;
double* __last;
public:
Iterator(MatrixRow& matrixRow) : __current(matrixRow.__data), __last(matrixRow.__data + matrixRow.__size) {}
Iterator(const Iterator& ref_iterator) : __current(ref_iterator.__current) {}
double& operator + (int n)
{
if(__current + n > __last)
{
throw std::out_of_range("Index out of range");
}
return *(__current + n);
}
}
Iterator begin()
{
return Iterator(__data);
}
Iterator end()
{
return Iterator(__data);
}
}