繁体   English   中英

如何声明 STL 样式 C++ hash Z1D78DC8ED51214E518B5114FE244?

[英]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 iteratorconst_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM