Проблема при реализации stl совместимого forward_iterator'а
Я новичок в C++ и в качестве учебного задания разрабатываю свой собственный HashMap, однако, при реализации forward iterator'а столкнулся с проблемой, при которой некоторые алгоритмы STL (например, std::find_if и std::find_if_not) не работают и анализатор выдает следующую ошибку:
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:162:10: error: no matching function for call to '__iterator_category' [clang-diagnostic-error]
std::__iterator_category(__first));
Когда делал через наследование (class Iterator : public std::iterator<std::forward_iterator_tag, V>), то всё работало исправно и никаких проблем не возникало, но преподаватель сказал, что этот способ устаревший и сейчас так делать не надо. В интернете видел способ с явным указанием member types от std::iterator, но когда я пытаюсь это сделать, то получаю ошибку.
Подскажите, пожалуйста, что я делаю не так? Как мне правильно создать stl совместимый forward iterator для моего класса в современном C++? Структура моего итератора такова:
class Iterator {
typedef std::ptrdiff_t difference_type;
typedef V value_type;
typedef HashNode* pointer;
typedef HashNode& reference;
typedef size_t size_type;
std::forward_iterator_tag iterator_category;
friend HashMap;`
private:
Iterator(pointer* table, size_t index, pointer node)
: table_(table), index_(index), node_(node) { ... }
Iterator(pointer* table, size_t index) : table_(table), index_(index) { ... }`
pointer* table_;
size_t index_;
pointer node_;
public:
K key() const { ... }
Iterator& operator++() { ... }
Iterator operator++(int) { ... }
bool operator==(const Iterator& other) const { ... }
bool operator!=(const Iterator& other) const { ... }
const value_type& operator*() const { ... }
value_type& operator*() { ... }
};
(Где V - это тип значения узла, K - тип ключа узла. Эти типы описаны в шаблоне основного класса Hashmap. HashNode - тип узла HashMap).
Ответы (2 шт):
std::forward_iterator_tag iterator_category;
Неправильно. Правильно так: using iterator_category = std::forward_iterator_tag; (или typedef, что то же самое).
Также заметьте, что в C++20 эти тайпдефы больше не обязательны, и угадываются автоматически.
Проблема была решена переносом всех параметров в область public. Вот рабочий вариант:
class Iterator {
friend HashMap;
private:
Iterator(pointer* table, size_t index, pointer node)
: table_(table), index_(index), node_(node) { ... }
Iterator(pointer* table, size_t index) : table_(table), index_(index) { ... }`
pointer* table_;
size_t index_;
pointer node_;
public:
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = V;
using pointer = HashNode*;
using reference = HashNode&;
using size_type = size_t;
K key() const { ... }
Iterator& operator++() { ... }
Iterator operator++(int) { ... }
bool operator==(const Iterator& other) const { ... }
bool operator!=(const Iterator& other) const { ... }
const value_type& operator*() const { ... }
value_type& operator*() { ... }
};