6

好的,我正在尝试制作一个快速的小类来作为一种哈希表。如果我能让它工作,那么我应该能够做到这一点:

  StringHash* hash = new StringHash;
  hash["test"] = "This is a test";
  printf(hash["test"]);

它应该打印出“这是一个测试”。

看起来我现在有两个问题。首先我这样做了:

const char* operator[](const char* key) {
  for(int i = 0; i < hashSize; ++i) {
    if(strcmp(hkeys[i], key) == 0) {return values[i];}
  }
  return NULL;
}

但是当我尝试查找一个值时,编译器会抱怨

错误:数组下标的无效类型 `StringHash*[const char[5]]'

其次 operator[]= 在这里似乎不是正确的语法。我能找到的唯一另一件事是 &operator[] 但我认为这不会起作用,因为我必须编写查找过程的代码???(该语法不是仅用于返回数组项引用吗?)

我在这里尝试做的事情甚至可能吗?任何建议表示赞赏。:)


似乎对我正在尝试做的事情有些困惑。我将发布我的代码:

http://pastebin.com/5Na1Xvaz


所有帮助后的成品:

http://pastebin.com/gx4gnYy8

4

8 回答 8

6

错误是因为hash是一个指针。改成:

StringHash hash;
于 2010-10-11T14:13:07.440 回答
4

其他答案与您的第一个问题有关。至于你的第二...

如果您返回一个引用,那么您将返回一个左值。您始终可以分配给左值。

是的,它(几乎)真的就是这么简单。不过,我建议您仔细阅读是否需要const在各个地方。

我记得读过的是,您应该为 提供一个const和一个非const重载operator[],如下所示:

MyType const &operator[](int index) const; // This is the array access version (no assignment allowed), which should work on const objects
MyType &operator[](int index);      // This is the array access or assignment version, which is necessarily non-const.

有关更多信息,请参阅此链接。

于 2010-10-11T14:19:48.283 回答
3

hash不是StringHash对象。它是一个指针。

你可以这样做:

(*hash)["test"] = "This is a test";

或者你可以问自己为什么首先需要一个指向它的指针,

StringHash hash;
hash["test" = "This is a test";

...或者即使你这样做,为什么你不会使用像auto_ptr.

#include <memory>
std::auto_ptr<StringHash> hash( new StringHash );
(*hash)["test"] = "This is a test";
于 2010-10-11T14:14:28.697 回答
2

StringHash hash;而不是new东西。C++ 不是 Java。:-)

于 2010-10-11T14:14:58.993 回答
2

第一个错误是您将 hash 声明为指针。指针类型已经可以与索引运算符一起使用。例如,pointer[3] 等价于 *(pointer+3)。你无法改变这种行为。使对象本身散列:

StringHash sh;

至于operator[]=,没有这样的东西。您的索引运算符应该只返回一个引用以使分配工作。这是一个简单的示例,说明它的外观:

class Indexable
{
   std::string arr[3];
public:
   std::string & operator[](int index) {
      return arr[index];
   }
   std::string const& operator[](int index) const {
      return arr[index];
   }
};
于 2010-10-11T14:23:06.620 回答
2

五个问题:

  1. hash是指向 StringHash 的指针,您必须取消引用它才能使用运算符:(*hash)["test"]
  2. 如果要分配给元素,则必须返回对元素类型的引用

    const char *& operator[] (const char* key);

    // ...

    (*hash)["test"] = "This is a test"; // will compile now

  3. null不是 C++ 中的关键字。使用 0 或NULL.

  4. operator []如果找不到元素,则必须为其分配空间。回归NULL不是一种选择。否则,尝试分配结果(*hash)["test"]将使您的程序崩溃。
  5. 使用 std::map 或 std::tr1::unordered_map 而不是编写自己的“快速”类。

做个混蛋:你知道那不是哈希表,对吧?

于 2010-10-11T14:23:48.617 回答
2

我首先会质疑为什么你要编写自己的 HashMap,因为有一些版本可用,尽管不是标准版本。

您的哈希映射是否存储 const char* 指针或 std::strings?(它可能存储 const char * 指针,如果它只是一个对存储在不会改变其生命周期的其他地方的数据的查找表)。

找不到项目时,operator[] 应该做什么?

现在让我假设答案是: - 是的,我们正在存储 const char * 指针,并且我们将 NULL 存储在一个空单元格中 - 当我们执行 hash[key]=value 时,我们希望将键与值相关联 - 如果我们只是这样做hash[key] 但不写,它不插入

这可以通过一个魔术对象来完成:当您将 const char * 分配给该对象时,它会插入或覆盖散列。您还可以进行从对象到 const char * 的隐式转换以进行读取。

不过这很复杂,最好坚持使用 map 的常规界面: operator[] 总是插入,而您使用不同的方法来查找。

于 2010-10-11T14:35:19.807 回答
1

你能用一个boost::unordered_map<std::string, std::string吗?然后你不必担心自己实现这个。

假设这是对您自己的某种练习:您可能来自不同的背景,但在 C++ 中,声明散列的正常方法是:

StringHash hash;

此外,您operator[]可能适用于印刷品,但不适用于作业。通常operator[],方法通过返回可以分配新值的非常量引用或代理对象来工作,而您的方法两者都没有。如果您能够使用 std::string,则可以重写您的方法以返回对哈希中应读取或分配的位置的非常量引用。

于 2010-10-11T14:26:26.907 回答