正确重载 [括号] 运算符用于哈希表获取和设置
Properly overloading [bracket] operator for hashtable get and set
我正在尝试实现一个哈希表类。我面临的问题是如何正确重载方括号运算符,以便从哈希表中获取键的值与将键设置为值是有区别的。
到目前为止,这是该类的外观:
template <typename K, typename V>
class HashTable {
typedef pair<K, V> KeyVal;
avl_tree <KeyVal> **TABLE;
unsigned TABLESIZE;
public:
HashTable( const unsigned & );
V& operator [] ( const K& ); //Setter
const V& operator [](const K&) const; //Getter
typedef unsigned (*hashtype)(const K&);
static hashtype Hash;
~HashTable();
};
这是括号的每个重载的实现:
template <typename K, typename V>
V& HashTable<K, V>::operator [] ( const K& ret ) {
unsigned index = HashTable<K, V>::Hash(ret) % TABLESIZE;
avl_tree <KeyVal> *ptr = AVL_TREE::find(TABLE[index], KeyVal(ret, 0));
if ( ptr == None ) ptr = (TABLE[index] = AVL_TREE::insert(TABLE[index], KeyVal(ret, 0)));
return ptr->data.second;
}
template <typename K, typename V>
const V& HashTable<K, V>::operator [](const K& ret) const {
avl_tree <KeyVal> *ptr = AVL_TREE::find(TABLE[HashTable<K, V>::Hash(ret) % TABLESIZE], KeyVal(ret, 0));
if (ptr == None) throw "Exception: [KeyError] Key not found exception.";
return ptr->data.second;
}
现在,如果我这样做:
cout << table["hash"] << "n"; //table declared as type HashTable<std::string, int>
我得到的输出为 0,但我希望它使用重载方括号的 getter 实现;即这应该引发异常。我该怎么做?
处理这种情况的常用方法是让operator[]
返回代理。
然后,对于代理重载operator T
大致与您在上面完成const
重载一样。重载operator=
就像您的非常量版本一样。
template <typename K, typename V>
class HashTable {
typedef pair<K, V> KeyVal;
avl_tree <KeyVal> **TABLE;
unsigned TABLESIZE;
template <class K, class V>
class proxy {
HashTable<K, V> &h;
K key;
public:
proxy(HashTable<K, V> &h, K key) : h(h), key(key) {}
operator V() const {
auto pos = h.find(key);
if (pos) return *pos;
else throw not_present();
}
proxy &operator=(V const &value) {
h.set(key, value);
return *this;
}
};
public:
HashTable( const unsigned & );
proxy operator [] ( const K& k) { return proxy(*this, k); }
typedef unsigned (*hashtype)(const K&);
static hashtype Hash;
~HashTable();
};
当你使用它时,你基本上有两种情况:
some_hash_table[some_key] = some_value;
value_type v = some_hash_table[some_key];
在这两种情况下,some_hash_table[some_key]
都会返回 proxy
的实例。在第一种情况下,您将分配给代理对象,以便调用代理的operator=
,将其传递some_value
,以便some_value
以key
作为其键添加到表中。
在第二种情况下,您尝试将 proxy
类型的对象分配给 value_type
类型的变量。显然,这不能直接赋值 - 但proxy::operator V
返回基础Hashtable
的值类型的对象 - 因此编译器调用它以生成可以分配给v
的值。反过来,它会检查表中是否存在正确的键,如果不存在,则会引发异常。
当成员函数或运算符的等效const
和非const
重载可用时,在非const
实例上调用该方法时,将选择非常量。仅当实例const
,或者通过const
引用或指针访问实例时,才会选择const
重载:
struct Foo
{
void foo() {}
void foo() const {}
};
void bar(const Foo& f) { f.foo();}
void baz(const Foo* f) { f->foo(); }
int main()
{
Foo f;
f.foo(); // non-const overload chosen
bar(f); // const overload chosen
bar(&f); // const overload chosen
const Foo cf; // const instance
cf.foo(); // const overload chosen
const Foo& rf = f; // const reference
rf.foo(); // const overload chosen
}
相关文章:
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- C++中的并发哈希表
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 与C++哈希表的基础知识混淆
- 调整大小和复制哈希表数组中的元素
- 带链接的基本哈希表
- C++哈希表中,两个相同的实现,但一个给出错误
- 如果索引不是整数,我们如何在 C++ 中插入哈希表
- 查找项目在哈希表中的位置
- 为什么C++ STL 哈希表 (unordered_map) 不接受向量作为键
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- 创建用于存储某些指针值的哈希表
- 用于开放寻址哈希表的高效C++ API
- 弹性令牌不适用于字符*哈希表
- 正确重载 [括号] 运算符用于哈希表获取和设置
- 在C++中创建用于字符串操作的哈希表
- 用于构建高效哈希表的字符串的唯一属性
- 哈希表单独链接中没有用于调用xxx的匹配函数