运算符[]=重载?

发布于 2024-09-27 03:17:48 字数 902 浏览 1 评论 0 原文

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

  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

Okay, I'm trying to make a quick little class to work as a sort of hash table. If I can get it to work then I should be able to do this:

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

And it should print out "This is a test".

It looks like I have 2 problems at this point. Firstly I did this:

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

But when I try to look up a value the compiler complains that

error: invalid types `StringHash*[const char[5]]' for array subscript

Secondly operator[]= does not appear to be the correct syntax here. The only other thing I could find was &operator[] but I don't think that will work since I have to code the lookup procedure??? (Isn't that syntax just used to return an array item reference?)

Is what I'm trying to do here even possible? Any advice appreciated. :)


Seems to be some confusion about what I'm trying to do. I'll post my code:

http://pastebin.com/5Na1Xvaz


Finished product after all the help:

http://pastebin.com/gx4gnYy8

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

画离情绘悲伤 2024-10-04 03:17:48

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

StringHash hash;

The error is because hash is a pointer. Change to:

StringHash hash;
木落 2024-10-04 03:17:48

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

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

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

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

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.

请参阅此链接了解更多信息。

The other answers relate to your first question. As for your second...

If you return a reference, then you're returning an lvalue. You can always assign to an lvalue.

Yes, it (pretty much) really is that simple. I recommend reading carefully for whether or not you need const in various places, though.

What I remember reading is that you should provide a const and a non-const overload for operator[], something like so:

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.

See this link for more information.

南笙 2024-10-04 03:17:48

我首先会问为什么当有一些可用版本(尽管不是标准版本)时你要编写自己的 HashMap。 (写于 2010 年,但现在有了 std::unordered_map)

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

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

现在让我假设答案是:

  • 是的,我们正在存储 const char * 指针,并且我们在空单元格中存储 NULL
  • 当我们执行 hash[key]=value 时,我们希望将 key 与 value 关联
  • 如果我们只执行 hash[key ] 但不要写,它不会插入

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

但这相当复杂,最好坚持使用映射的常规接口:operator[] 总是插入,并且您使用不同的方法来查找。

I would firstly question why you are writing your own HashMap when there are some versions available albeit not a standard one. (that was written in 2010, but there is now std::unordered_map)

Does your hash-map store const char* pointers or std::strings? (It might store const char * pointers if it is simply a lookup table to data stored elsewhere that is not going to change its lifetime).

What is operator[] supposed to do when the item is not found?

Now let me assume that the answers are:

  • Yes we are storing const char * pointers, and we store a NULL in an empty cell
  • When we perform hash[key]=value we want to associate key with value
  • If we just do hash[key] but don't write, it does not insert

This can be done with a magic object: when you assign a const char * to this object it inserts or overwrites to the hash. You can also have an implicit conversion from the object to const char * for reading.

This is quite complex though and it is preferable to stick to the regular interface of map: operator[] always inserts and you use a different method just to lookup.

蝶舞 2024-10-04 03:17:48

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";

hash isn't a StringHash object. Its a pointer to one.

You can do this:

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

Or you can ask yourself why you need a pointer to it in the first place,

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

... or even if you do, why you wouldn't use a smart pointer like auto_ptr.

#include <memory>
std::auto_ptr<StringHash> hash( new StringHash );
(*hash)["test"] = "This is a test";
夏花。依旧 2024-10-04 03:17:48

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

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];
   }
};

The first error is that you declared hash to be a pointer. Pointer types can already be used with the index operator. For example, pointer[3] is equivalent to *(pointer+3). You can't change that behaviour. Make hash the object itself:

StringHash sh;

As for operator[]=, there is no such thing. Your index operator should just return a reference in order to make the assignment work. Here's a simple example of how this would look like:

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];
   }
};
嘿看小鸭子会跑 2024-10-04 03:17:48

五个问题:

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

    const char *&运算符[](const char *键);

    <代码>// ...

    (*hash)["test"] = "这是一个测试"; // 现在将编译

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

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

只是说个混蛋:你知道这不是一个哈希表,对吧?

Five problems:

  1. hash is a pointer to a StringHash, you have to dereference it to use operators: (*hash)["test"]
  2. If you want to assign to the element, you have to return a reference to the element type

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

    // ...

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

  3. null isn't a keyword in C++. Use 0 or NULL.

  4. operator [] has to allocate space for an element if it isn't found. Returning NULL isn't an option. Otherwise, trying to assign to the result of (*hash)["test"] will crash your program.
  5. Use std::map or std::tr1::unordered_map instead of writing your own "quick" class.

And just to be a jerk: You know that isn't a hash table, right?

ζ澈沫 2024-10-04 03:17:48

编写StringHash hash;而不是new。 C++ 不是 Java。 :-)

Write StringHash hash; instead of the new thing. C++ isn't Java. :-)

双手揣兜 2024-10-04 03:17:48

您可以使用 boost::unordered_map 吗?那么您就不必担心自己实现这一点。

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

StringHash hash;

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

Are you able to use a boost::unordered_map<std::string, std::string? Then you don't have to worry about implementing this on your own.

Assuming it's an exercise of some sort for yourself:
You may come from different background, but in C++ the normal way to declare your hash would be:

StringHash hash;

Additionally your operator[] might work for the print but it won't work for the assignment. Normally operator[] methods work by returning a non-const reference or a proxy object to which the new values can be assigned, and yours does neither. If you were able to use std::string, you could rewrite your method to return a non-const reference to the position within the hash that should be read or assigned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文