[英]How to declare STL style C++ hash map iterator?
这是我在 C++14 中的 HashMap 示例:
#include <string>
#include <utility>
template <class K, class V> class MyNode {
public:
std::pair<const K, V> value;
};
template <class K, class V, class NodePtr> class MyIterator {
public:
MyIterator(NodePtr node = nullptr) : node_(node) {}
~MyIterator() = default;
MyIterator(const MyIterator &) = default;
MyIterator &operator=(const MyIterator &) = default;
std::pair<const K, V> &operator*() { return node_->value; }
const std::pair<const K, V> &operator*() const { return node_->value; }
std::pair<const K, V> *&operator->() { return &(node_->value); }
const std::pair<const K, V> *operator->() const { return &(node_->value); }
MyIterator<K, V, NodePtr> &operator++() { return *this; }
MyIterator<K, V, NodePtr> operator++(int) { return *this; }
bool operator==(const MyIterator<K, V, NodePtr> &other) {
return node_ == other.node_;
}
bool operator!=(const MyIterator<K, V, NodePtr> &other) {
return node_ != other.node_;
}
private:
NodePtr node_;
};
template <class K, class V> class MyHashMap {
public:
using Iterator = MyIterator<K, V, MyNode<K, V> *>;
using ConstIterator = MyIterator<K, V, const MyNode<K, V> *>;
Iterator begin() { return Iterator(&node); }
ConstIterator begin() const { return ConstIterator(&node); }
ConstIterator cbegin() const { return ConstIterator(&node); }
Iterator end() { return Iterator(nullptr); }
ConstIterator end() const { return ConstIterator(nullptr); }
ConstIterator cend() const { return ConstIterator(nullptr); }
MyNode<K, V> node;
};
void test(const int &a) {}
int main(void) {
MyHashMap<int, int> hm;
for (MyHashMap<int, int>::ConstIterator i = hm.begin(); i != hm.end(); i++) {
test(i->second);
}
for (MyHashMap<int, int>::ConstIterator i = hm.cbegin(); i != hm.cend();
i++) {
test(i->second);
}
return 0;
}
编译方式: clang++ -std=c++14 main.cpp -o main.exe
这给了我:
main.cpp:53:43: error: no viable conversion from 'MyIterator<[2 * ...], MyNode<int, int> *>' to 'MyIterator<[2 * ...], const MyNode<int, int> *>'
for (MyHashMap<int, int>::ConstIterator i = hm.begin(); i != hm.end(); i++) {
^ ~~~~~~~~~~
main.cpp:11:3: note: candidate constructor not viable: no known conversion from 'MyHashMap<int, int>::Iterator' (aka 'MyIterator<int, int, MyNode<int, int> *>') to 'const MyNode<int, int> *' for 1st
argument
MyIterator(NodePtr node = nullptr) : node_(node) {}
^
main.cpp:13:3: note: candidate constructor not viable: no known conversion from 'MyHashMap<int, int>::Iterator' (aka 'MyIterator<int, int, MyNode<int, int> *>') to
'const MyIterator<int, int, const MyNode<int, int> *> &' for 1st argument
MyIterator(const MyIterator &) = default;
^
main.cpp:18:49: error: non-const lvalue reference to type 'std::pair<const int, int> *' cannot bind to a temporary of type 'const std::pair<const int, int> *'
std::pair<const K, V> *&operator->() { return &(node_->value); }
^~~~~~~~~~~~~~~
main.cpp:58:11: note: in instantiation of member function 'MyIterator<int, int, const MyNode<int, int> *>::operator->' requested here
test(i->second);
^
2 errors generated.
我的 HashMap 和迭代器声明是否正确?
你using
错误的方式。
您没有任何Node<K, const V>
可以指向。
为了符合Container ,您应该拼写 it iterator
和const_iterator
,并提供另一个using
s
您要么需要专门化std::iterator_traits
,要么提供它需要的定义。
template <class K, class V>
class MyHashMap {
public:
using iterator = MyIterator<K, V, Node<K, V>>;
using const_iterator = MyIterator<K, V, const Node<K, V>> = ConstIterator;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.