好吧,我正在尝试创建一个快速的小类来充当某种哈希表。如果我能让它工作,那么我应该能够做到这一点:
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
发布评论
评论(8)
该错误是因为
hash
是一个指针。更改为:The error is because
hash
is a pointer. Change to:其他答案与你的第一个问题有关。至于你的第二个......
如果你返回一个引用,那么你将返回一个左值。您始终可以分配给左值。
是的,它(几乎)确实就是这么简单。不过,我建议仔细阅读您是否在各个地方需要
const
。我记得读过的是,您应该为
operator[]
提供一个const
和一个非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 foroperator[]
, something like so:See this link for more information.
我首先会问为什么当有一些可用版本(尽管不是标准版本)时你要编写自己的 HashMap。 (写于 2010 年,但现在有了 std::unordered_map)
您的哈希映射是否存储 const char* 指针或 std::string? (如果它只是一个存储在其他地方的数据的查找表,并且不会改变其生命周期,那么它可能会存储 const char * 指针)。
当找不到该项目时,operator[] 应该做什么?
现在让我假设答案是:
这可以使用魔术对象来完成:当您将 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:
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.
hash
不是StringHash
对象。它是一个指向一的指针。您可以这样做:
(*hash)["test"] = "This is a test";
或者您可以问自己为什么首先需要一个指向它的指针,
...或者即使您这样做,为什么您不使用像
auto_ptr
这样的智能指针。hash
isn't aStringHash
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,
... or even if you do, why you wouldn't use a smart pointer like
auto_ptr
.第一个错误是您将 hash 声明为指针。指针类型已经可以与索引运算符一起使用。例如,指针[3]相当于*(指针+3)。你无法改变这种行为。让hash成为对象本身:
至于operator[]=,则没有这样的东西。您的索引运算符应该只返回一个引用以使分配起作用。下面是一个简单的示例:
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:
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:
五个问题:
hash
是一个指向 StringHash 的指针,你必须取消引用它才能使用运算符:(*hash)["test"]
如果你想分配给元素,你必须返回元素类型的引用
const char *&运算符[](const char *键);
<代码>// ...
(*hash)["test"] = "这是一个测试"; // 现在将编译
null
不是 C++ 中的关键字。使用 0 或NULL
。operator []
必须为该元素分配空间。返回NULL
不是一个选项。否则,尝试分配给(*hash)["test"]
的结果将使您的程序崩溃。只是说个混蛋:你知道这不是一个哈希表,对吧?
Five problems:
hash
is a pointer to a StringHash, you have to dereference it to use operators:(*hash)["test"]
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
null
isn't a keyword in C++. Use 0 orNULL
.operator []
has to allocate space for an element if it isn't found. ReturningNULL
isn't an option. Otherwise, trying to assign to the result of(*hash)["test"]
will crash your program.And just to be a jerk: You know that isn't a hash table, right?
编写
StringHash hash;
而不是new
。 C++ 不是 Java。 :-)Write
StringHash hash;
instead of thenew
thing. C++ isn't Java. :-)您可以使用
boost::unordered_map 吗?那么您就不必担心自己实现这一点。
假设这是对你自己的某种练习:
您可能来自不同的背景,但在 C++ 中声明散列的正常方法是:
另外,您的
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:
Additionally your
operator[]
might work for the print but it won't work for the assignment. Normallyoperator[]
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.