Problem with C ++ operator overloading []

I'm still new to C ++, so I run into new issues every day.

Today came the rotation of the operator []:

I am creating a new generic List class because I don't really like std. I'm trying to give it a warm and fuzzy look at the C # Collections.Generic List, so I want to have access to items by index. To interrupt the chase:

Excerpt 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; } 

This is the code for operators. A template uses a "template", so as far as I've seen in some tutorials, this is the correct way to overload an operator.

However, when I try to access by index, for example:

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

I get

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

referring to the string "int a = myList [0]". Basically the "myList [0]" type is still "Collections :: List", although it should have been just an int. How to come?

+4
source share
3 answers

Since myList is a pointer, myList[0] does not call operator[] , it returns Collections::List<int>* . You want (*myList)[0] . Or better yet, Collections::List<int>& myRef = *myList; and then use myRef[0] (Another option does not allocate memory for myList on the heap, you can create it on the stack using Collections::List<int> myList and then use the operator on it . ).

+14
source

myList has a pointer to a List type, not a List. In the case where an expression of the type of the pointer is accompanied by an integral value enclosed in square brackets (for example, myList [0]), the result is identical to "add 0 to the value of the pointer and look for it." The result of adding 0 to the address of the list and dereferencing it simply leads to the list.

Typically, programmers used for C # and Java use C ++ new too much. In a published example, it is better to use Collections::List<int> myList; and . instead of -> .

+2
source

It's good that you want to learn C ++ and practice writing your own collections, but your logic is probably wrong.

std::vector and std::deque already allow random access by constant time. std::deque more like a list in which it allows you to insert and delete constant time from either end and does not cancel links or iterators due to inserts.

It seems that you are mixing your collection with its iterator into one class, so that the collection contains the current position. I am pretty sure that C # collections are not implemented this way.

Finally, I would suggest that your MoveCursor team is O (N), which means that in fact you don’t have random access at all.

If you need fast random access and insert time, it is best to use O (log N) using a tree structure with each node in the tree indicating the number of elements in each branch below. So you can find the nth element recursive in the right way. The insert is also O (log N), since you have to regenerate the tree by changing the counts, and of course you have to balance the tree regularly.

0
source

Source: https://habr.com/ru/post/1341111/


All Articles