2009-10-24 46 views
3

我正在为我的数据结构类编写一个哈希表,并且我想为我的实现添加一点语法糖。重载括号访问和分配C++

template <typename HashedObj, typename Object> 
Object & Dictionary<HashedObj, Object>::operator[](HashedObj & key) 
{ 
    return items.lookup(key); 
} 

,当我做类似的cout < <的dict [ “的myKey”]这工作正常。 但是我怎样才能使用括号进行赋值?喜欢的东西:

dict["mykey"] = "something"; 

不,这不是我的家庭作业(没有双关语意),我只是想学C++好一点的一部分。

+0

顺便说一句,你用什么类型的'HashedObj'当你声明你的Dictionary用于字符串键?像上面例子中的“mykey”一样。 – AnT 2009-10-24 18:38:19

+0

因为你正在返回一个引用,赋值操作符应该按照你期望的方式工作。唯一的问题发生在lookup()找不到key时,你会怎么做? – 2009-10-24 20:01:01

+0

在我的测试中,我使用字符串: Dictionary dict; – Matt 2009-10-24 20:28:49

回答

5

目前尚不清楚你到底在问什么。您提交的代码已经支持分配。只要做到这一点,并随时工作(或至少应该编译)。它使您的超载[]被使用的赋值运算符的哪一面完全没有区别。它在左侧(LHS)的工作方式与在作业的右侧(RHS)的工作方式完全相同(或作为<<的操作数,如在原始文章中那样)。您的[]返回对Object的引用,然后实际分配由您的Object类型的赋值运算符处理,这意味着[]本身并未真正涉及实际分配。

这里真正的问题是你希望你的[]在某些特殊情况下行事。如果你的钥匙不在桌子上,会发生什么?参考什么Object是你的lookup要在这种情况下返回?

从您发布的内容中弄清楚这一点是不容置疑的。我看到它返回一个参考,所以返回NULL是没有问题的。它是否为给定的键插入一个新的空的Object?如果是这样,那么你不必做任何事情。您的[]已经完全准备好用于分配的LHS。 (这是如何std::map作品,BTW []

如果您lookup返回到一个特殊的“保镖” Object参考,你必须采取特殊步骤。您可能不想将任何内容分配给“警卫”对象,因此您必须以某种方式“禁用”其赋值运算符,然后完成。其余的应该按原样工作。

如果您的lookup在不存在密钥的情况下引发异常,那么您必须决定在分配的LHS上使用[]时是否这样。如果是这样,那么你不需要做任何事情。如果没有,那么它将需要一些额外的工作...

因此,再次,如果你通过一个不存在的密钥lookup会发生什么?

P.S.此外,通常将[](和lookup)与const HashedObj&参数或仅HashedObj参数一起声明会更有意义。在你的例子中,非const引用看起来很奇怪,可能会导致一些(实际上,在大多数情况下)的问题。我很惊讶它现在适合你...

+0

我想它已经支持分配。我觉得这会比这更难!我并不太担心这个简单程序的特殊情况,但感谢您指出它们。 – Matt 2009-10-24 17:48:00

+0

我支持通过=运算符进行赋值。 – Alexandru 2009-10-24 18:18:50

+0

@Matt:为了100%清楚,'operator []'返回一个'Object'引用。它是必须支持分配的“对象”类。 'Dictionary'类也可以支持赋值,但在这里不会执行。 – 2009-10-24 18:23:36

3

您需要重载2次。一个是const,它将是data access部分,另一个将返回一个引用,它将作为“setter”。

2

您要找的是和std::map中的重载支架操作符相似的功能。在std::map中,括号操作符执行查找并返回对与特定键相关联的对象的引用。如果该映射不包含任何与该键关联的对象,则该操作员使用默认构造函数将新对象插入到映射中。

所以,如果你有std::map<K,V> mymap,然后调用mymap[someKey]要么返回引用与someKey相关联的值,否则将通过调用V()(V的默认构造函数),然后返回创建V类型的新对象对新对象的引用,它允许调用者为对象分配一个值。