C++ []运算符重载问题
我还是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于
myList
是一个指针myList[0]
不会调用operator[]
,因此它返回Collections::List; *。您想要的是
(*myList)[0]
。或者更好的是,Collections::List& myRef = *myList;
然后使用myRef[0]
(其他选项是不在堆上为myList
分配内存,您可以在堆栈上创建它使用Collections::ListmyList
,然后使用.
运算符)。Since
myList
is a pointermyList[0]
doesn't invokeoperator[]
, it returnsCollections::List<int>*
. What you want is(*myList)[0]
. Or better still,Collections::List<int>& myRef = *myList;
and then usemyRef[0]
(Other option is not allocate the memory formyList
on the heap, you can create it on stack usingCollections::List<int> myList
and then use.
operator on it).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->
.很好,您想学习 C++ 并练习编写自己的集合,但您的逻辑可能有缺陷。
std::vector
和std::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
andstd::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.