C++ []运算符重载问题

发布于 2024-10-19 00:38:42 字数 1031 浏览 4 评论 0原文

我还是 C++ 新手,所以每天都会遇到新问题。

今天轮到 [] 运算符:

我正在为自己创建一个新的通用 List 类,因为我不太喜欢 std 的类。我试图给它 C# 的 Collections.Generic List 温暖而模糊的外观,所以我确实希望能够通过索引访问元素。切入正题:

模板摘录:

T& operator[](int offset)
    {
        int translateVal = offset - cursorPos;

        MoveCursor(translateVal);

        return cursor->value;
    }

    const T& operator[](int offset) const
    {
        int translateVal = offset - cursorPos;

        MoveCursor(translateVal);

        return cursor->value;
    }

这是操作员的代码。模板使用“模板”,因此据我在一些教程中看到的,这是进行运算符重载的正确方法。

然而,当我尝试按索引访问时,例如:

Collections::List<int> *myList;
myList = new Collections::List<int>();
myList->SetCapacity(11);
myList->Add(4);
myList->Add(10);
int a = myList[0];

我收到

    no suitable conversion function from "Collections::List<int>" to "int" exists

错误,引用“int a = myList[0]”行。基本上“myList[0]”类型仍然是“Collections::List”,尽管它应该只是 int。怎么会?

I'm still new to C++ so I daily run into new problems.

Today came the [] operator's turn:

I'm making myself a new generic List class because I don't really like the std's one. I'm trying to give it the warm and fuzzy look of the C#'s Collections.Generic List, so I do want to be able to access elements by index. To cut to the chase:

Extract from the template:

T& operator[](int offset)
    {
        int translateVal = offset - cursorPos;

        MoveCursor(translateVal);

        return cursor->value;
    }

    const T& operator[](int offset) const
    {
        int translateVal = offset - cursorPos;

        MoveCursor(translateVal);

        return cursor->value;
    }

That's the code for the operators. The template uses "template", so as far as I saw on some tutorials, that's the correct way to do operator overloading.

Nevertheless, when I'm trying to access by index, e.g.:

Collections::List<int> *myList;
myList = new Collections::List<int>();
myList->SetCapacity(11);
myList->Add(4);
myList->Add(10);
int a = myList[0];

I get the

    no suitable conversion function from "Collections::List<int>" to "int" exists

error, referring to the "int a = myList[0]" line. Basically "myList[0]" type's is still "Collections::List", although it should have been just int. How Come?

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

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

发布评论

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

评论(3

我很OK 2024-10-26 00:38:42

由于 myList 是一个指针 myList[0] 不会调用 operator[],因此它返回 Collections::List; *。您想要的是 (*myList)[0]。或者更好的是,Collections::List& myRef = *myList; 然后使用 myRef[0] (其他选项是不在堆上为 myList 分配内存,您可以在堆栈上创建它使用 Collections::ListmyList ,然后使用 . 运算符)。

Since myList is a pointer myList[0] doesn't invoke operator[], it returns Collections::List<int>*. What you want is (*myList)[0]. Or better still, Collections::List<int>& myRef = *myList; and then use myRef[0] (Other option is not allocate the memory for myList on the heap, you can create it on stack using Collections::List<int> myList and then use . operator on it).

你好,陌生人 2024-10-26 00:38:42

myList 的类型是指向 List 的指针,而不是 List。如果指针类型的表达式后跟方括号内的整数值(例如 myList[0]),则结果与“向指针值添加 0 并取消引用”相同它”。将 0 添加到列表的地址并取消引用它的结果只是生成列表。

对于习惯 C# 和 Java 的程序员来说,过度使用 C++ new 是很常见的。在发布的示例中,最好使用 Collections::List; myList;. 运算符而不是 ->

myList has type pointer to List, not List. In the case where an expression of pointer type is followed by an integral value enclosed in square brackets, (such as myList[0]), the result is identical to "add 0 to the pointer value and dereference it". The result of adding 0 to the address of the list and dereferencing it simply yields the list.

It is common for programmers used to C# and Java to overuse C++ new. In the posted example it is better to use Collections::List<int> myList; and the . operator instead of ->.

憧憬巴黎街头的黎明 2024-10-26 00:38:42

很好,您想学习 C++ 并练习编写自己的集合,但您的逻辑可能有缺陷。

std::vectorstd::deque 已经允许恒定时间随机访问。 std::deque 更像是一个列表,因为它允许在任一端进行恒定时间插入和删除,并且不会因插入而使引用或迭代器无效。

您似乎还将集合与其迭代器混合到一个类中,以便集合包含当前位置。我非常确定 C# 集合不是以这种方式实现的。

最后我想你的 MoveCursor 命令是 O(N) 这意味着你根本没有真正的随机访问。

如果你想要快速的随机访问和插入时间,你可以通过使用树结构来管理最好的时间复杂度是 O(log N),树上的每个节点指示其下面每个分支中的元素数量。因此,您可以找到沿正确路径递归的第 n 个元素。插入也是 O(log N),因为您必须递归修改计数的树,并且您当然必须定期平衡树。

Good that you want to learn C++ and practise writing your own collections but your logic is probably flawed.

std::vector and std::deque already allow constant-time random access. std::deque is more like a list in that it allows constant-time insertion and removal at either end and does not invalidate references or iterators due to insertions.

You also seem to be mixing your collection with its iterator into one class, so that a collection contains a current position. I am pretty certain C# collections are not implemented that way.

Finally I would imagine your MoveCursor command is O(N) which means you do not really have random-access at all.

If you want fast random access and insertion time the best you can manage is O(log N) by using a tree structure, with each node on the tree indicating the number of elements in each branch below it. Thus you can find the nth element recursing down the right path. Insertion is also O(log N) as you have to recurse up the tree modifying the counts, and you will of course have to regularly balance the tree.

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