C++ 中重载 [] 运算符
我试图重载 c++ 中的 [] 运算符,以便我可以从数据结构中分配/获取值,就像 c# 中使用的字典一样:
Array["myString"] = 等。
这在 c++ 中可能吗?
我尝试使运算符超载,但似乎不起作用,
Record& MyDictionary::operator[] (string& _Key)
{
for (int i = 0; i < used; ++i)
{
if (Records[i].Key == _Key)
{
return Records[i];
}
}
}
谢谢。
Im trying to overload the [] operator in c++ so that I can assign / get values from my data structure like a dictionary is used in c#:
Array["myString"] = etc.
Is this possible in c++?
I attempted to overload the operator but it doesnt seem to work,
Record& MyDictionary::operator[] (string& _Key)
{
for (int i = 0; i < used; ++i)
{
if (Records[i].Key == _Key)
{
return Records[i];
}
}
}
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的代码处于正确的轨道上 - 您拥有正确的函数签名 - 但您的逻辑有点缺陷。特别是,假设您完成此循环而没有找到您要查找的键:
如果发生这种情况,您的函数不会返回值,这会导致未定义的行为。由于它返回一个引用,因此当您尝试使用该引用时,这可能会导致严重的崩溃。
要解决此问题,您需要添加一些行为以确保您不会从函数末尾掉下来。一种选择是将键添加到表中,然后返回对该新表条目的引用。这是 STL
std::map
类的operator[]
函数的行为。另一种方法是抛出一个异常,表示密钥不存在,这确实有一个有点违反直觉的缺点。在一个完全不相关的注释中,我应该指出,从技术上讲,您不应该将此函数的参数命名为
_Key
。 C++ 标准规定,任何以两个下划线开头的标识符名称(即__myFunction
)或一个下划线后跟一个大写字母(如_Key
示例中所示)都被保留出于他们认为必要的任何目的而实施。他们可以将标识符#define 为一些无意义的东西,或者将其映射到某些编译器内部函数。如果您从一个平台转移到另一个平台,这可能会导致您的程序停止编译。要解决此问题,请将K
设置为小写 (_key
),或完全删除下划线 (Key
)。希望这有帮助!
Your code is on the right track - you've got the right function signature - but your logic is a bit flawed. In particular, suppose that you go through this loop without finding the key you're looking for:
If this happens, your function doesn't return a value, which leads to undefined behavior. Since it's returning a reference, this is probably going to cause a nasty crash the second that you try using the reference.
To fix this, you'll need to add some behavior to ensure that you don't fall off of the end of the function. One option would be to add the key to the table, then to return a reference to that new table entry. This is the behavior of the STL
std::map
class'soperator[]
function. Another would be to throw an exception saying that the key wasn't there, which does have the drawback of being a bit counterintuitive.On a totally unrelated note, I should point out that technically speaking, you should not name the parameter to this function
_Key
. The C++ standard says that any identifier name that starts with two underscores (i.e.__myFunction
), or a single underscore followed by a capital letter (as in your_Key
example) is reserved by the implementation for whatever purposes they might deem necessary. They could#define
the identifier to something nonsensical, or have it map to some compiler intrinsic. This could potentially cause your program to stop compiling if you move from one platform to another. To fix this, either make theK
lower-case (_key
), or remove the underscore entirely (Key
).Hope this helps!
与此相关的是,operator[](const Key& key) 的问题之一是,正如 templatetypedef 所说,为了返回引用,它需要是非常量的。
要拥有 const 访问器,您需要一个可以返回失败情况值的方法。在 STL 中,这是通过使用
find()
和迭代器的使用以及使用end()
指示失败来完成的。另一种方法是返回一个指针,其中 null 表示失败。当默认构造的记录毫无意义时,这可能是合理的。这也可以通过数组运算符来完成:
当然有一种观点认为operator[]应该返回一个引用。在这种情况下,您很可能也实现
find()
并根据它实现operator[]
。要实现 find(),您需要定义一个迭代器类型。方便的类型将取决于实施。例如,如果 Records[] 是一个普通的旧数组:
On a related note, one of the problems with
operator[](const Key& key)
is that, as templatetypedef states, in order to return a reference it needs to be non-const.To have a const accessor, you need a method that can return a fail case value. In STL this is done through using
find()
and the use of iterators and havingend()
indicate a fail.An alternative is to return a pointer, with a null indicating a fail. This is probably justified where the default constructed Record is meaningless. This can be also be done with the array operator:
There is certainly a view that
operator[]
should return a reference. In that case, you'd most likely implementfind()
as well and implementoperator[]
in terms of it.To implement find() you need to define an iterator type. The convenient type will depend in implementation. For example, if Records[] is a plain old array: