C++ 中重载 [] 运算符

发布于 2024-10-19 11:42:06 字数 349 浏览 3 评论 0原文

我试图重载 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 技术交流群。

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

发布评论

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

评论(2

命比纸薄 2024-10-26 11:42:07

您的代码处于正确的轨道上 - 您拥有正确的函数签名 - 但您的逻辑有点缺陷。特别是,假设您完成此循环而没有找到您要查找的键:

for (int i = 0; i < used; ++i)
{
    if (Records[i].Key == _Key)
    {
        return Records[i]; 
    }
}

如果发生这种情况,您的函数不会返回值,这会导致未定义的行为。由于它返回一个引用,因此当您尝试使用该引用时,这可能会导致严重的崩溃。

要解决此问题,您需要添加一些行为以确保您不会从函数末尾掉下来。一种选择是将键添加到表中,然后返回对该新表条目的引用。这是 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:

for (int i = 0; i < used; ++i)
{
    if (Records[i].Key == _Key)
    {
        return Records[i]; 
    }
}

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's operator[] 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 the K lower-case (_key), or remove the underscore entirely (Key).

Hope this helps!

萌能量女王 2024-10-26 11:42:07

与此相关的是,operator[](const Key& key) 的问题之一是,正如 templatetypedef 所说,为了返回引用,它需要是非常量的。

要拥有 const 访问器,您需要一个可以返回失败情况值的方法。在 STL 中,这是通过使用 find() 和迭代器的使用以及使用 end() 指示失败来完成的。

另一种方法是返回一个指针,其中 null 表示失败。当默认构造的记录毫无意义时,这可能是合理的。这也可以通过数组运算符来完成:

Record* MyDictionary::operator[] (const string& keyToFind) const
{ 

    for (int i = 0; i < used; ++i)
    {
        if (Records[i].Key == keyToFind)
        {
            return &Records[i]; 
        }
    }
    return 0;
}

当然有一种观点认为operator[]应该返回一个引用。在这种情况下,您很可能也实现 find() 并根据它实现 operator[]

要实现 find(),您需要定义一个迭代器类型。方便的类型将取决于实施。例如,如果 Records[] 是一个普通的旧数组:

typedef Record* iterator;
typedef const Record* const_iterator;
const_iterator MyDictionary::end()const
{
    return Records + used;
}
const_iterator MyDictionary::begin() const
{
    return Records;
}
const_iterator MyDictionary::find(const string& keyToFind) const
{ 
    for (iterator it = begin(); it != end(); ++it)
    {
        if (it->Key == keyToFind)
        {
            return it; 
        }
    }
    return end();
}

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 having end() 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:

Record* MyDictionary::operator[] (const string& keyToFind) const
{ 

    for (int i = 0; i < used; ++i)
    {
        if (Records[i].Key == keyToFind)
        {
            return &Records[i]; 
        }
    }
    return 0;
}

There is certainly a view that operator[] should return a reference. In that case, you'd most likely implement find() as well and implement operator[] 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:

typedef Record* iterator;
typedef const Record* const_iterator;
const_iterator MyDictionary::end()const
{
    return Records + used;
}
const_iterator MyDictionary::begin() const
{
    return Records;
}
const_iterator MyDictionary::find(const string& keyToFind) const
{ 
    for (iterator it = begin(); it != end(); ++it)
    {
        if (it->Key == keyToFind)
        {
            return it; 
        }
    }
    return end();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文