| cire (1845) | |||
Perhaps that deserves some clarification. When I said
And, as Coder777 indicates, terminating the program is usually the correct thing to do when such a logic error occurs, so ignoring the exception isn't unreasonable. | |||
|
|
|||
| Volatile Pulse (1329) | |
|
So...it's better to just forget about the exceptions and let myself or someone else who writes code containing my list figure it out on their own? I'm not trying to be ignorant with this response, I'm just trying to find out what the proper course would be to take. If I don't have to use exceptions, then, simply, I just won't. But if it is suggested that I use exceptions, then I will. I've tried avoiding exceptions for majority of the years I've been programming mainly because I never needed them and learned that they shouldn't be relied upon. To clarify these last few posts in a more simpler question: 1) Do I need exceptions? 2) Do you recommend using them in this situation? 3) What benefits do I have over just ignoring returning something that doesn't exist? Thanks guys and/or ladies. | |
|
|
|
| Volatile Pulse (1329) | ||||||
Alright, I went back to make my code a little neater and more manageable by separating the declarations and definitions and ran into some issues:
But I get these errors:
I'm assuming it has to do with this part: vp::list<T>::iteratorTo me, that looks like the correct 'typename' but I'm unsure as to what it's complaining about. Can I not break apart the definitions like this? | ||||||
|
|
||||||
| cire (1845) | |||||
No, you don't need them.
Yes.
That's been covered.
Correct. In fact, the error message tells you how to correct it - put 'typename' before 'vp::list<T>::iterator' Note that 'typename' is a keyword like 'new' and 'template'. | |||||
|
|
|||||
| Volatile Pulse (1329) | |
|
That seemed really easy. -.- But let me finish tidying this up then I'll work on the exceptions. I have a few hours yet tonight to work on this so hopefully I'll get it to where I'm happy but my mom's dog is making it hard by laying on my laptop keyboard. | |
|
|
|
| Volatile Pulse (1329) | |||||
Alright, I got a good portion of my list working now and I started reading up on exceptions, still fail to see the benefit over just using if statements, but whatever. Here's what I got so far:
The program still crashes after displaying the message, I'm assuming because I fail to return anything from the function, but I have two issues, which are the same as before. What do I "return" and I don't need to display a message to the screen, but I have no clue what should be thrown/caught. Any advice? Edit: Here is another approach I took as well so that it still returns something, but it returns a local variable which will cause problems:
| |||||
|
Last edited on
|
|||||
| cire (1845) | |||
Your job isn't to handle the exception. Your job is to generate it.
| |||
|
|
|||
| Volatile Pulse (1329) | |
|
That...is...so...AWESOME! I never knew something like that existed. Is it only g++ that handles uncaught exceptions like this or is it standard amongst compilers? That's where I was getting confused. I thought that I had to personally handle the exceptions with "catch". Now, I assume there is a generic way to "catch" these exceptions so that you can prevent the program from crashing as well. Meaning, if someone doesn't want to error test, they could possibly call a logic_catch() function or something and handle it how they see fit instead of just letting the program crash? I'm just trying to learn some things. I'll have to delve further into stdexcept as well, I presume. | |
|
|
|
| Volatile Pulse (1329) | |||||||||
So, I've been working on adding more things to my list and decided on adding in some more ctors, mainly copy ctor and a sized ctor, and now things are broke. I'm getting SEGFAULTS at the end() function. Here is all of the code so far:
I'm trying to use the for-range loop and running the debugger, I get errors at the end function. I swore I had this issue before but got it fixed. I did also try using a regular for loop and still had the same issues. Here is the specific end function though:
I changed lastNode->next to just lastNode, but then it skips the last element. What am I missing? Edit: I figured it out. The SEGFAULT is being caused by and empty list. I'm going to try returning NULL if it's empty. Edit: Something else that I thought was really weird was that when using auto, a derefence operator isn't required on it to get the node's memory location, it seems to be forbidden. However, when making the type of it vp::list<int>::iterator, it's required. What does auto set it to? The private node?
| |||||||||
|
Last edited on
|
|||||||||
| cire (1845) | |||||
vp::list<int> myList1;invokes:
then end:
So invoking end causes a null pointer to be dereferenced. | |||||
|
|
|||||
| Volatile Pulse (1329) | |||||||
Yeah, I figured that one out. I simply changed end to this:
But I am concerned about the way auto behaves. I understood that it determines the data type automatically from the context of how it's used, but I'm confused as to what auto is in this sense:
I have tried looking around for a way to deduce what data type auto would transform into, but I couldn't find anything in this situation. | |||||||
|
|
|||||||
| cire (1845) | |
|
It will be the type your list::iterator::operator* returns. Which, in this case is a pointer to a node. That probably isn't quite right. An iterator shouldn't be returning a pointer to an implementation detail. It should be returning a reference to the data that is held by the node. Users iterating through a list shouldn't be concerned about next or previous pointers or what the data is called internally by the list. | |
|
|
|
| coder777 (2377) | |||
in addition to what cire said: In STL the end iterator is always excluded from processing, hence it would suffice to write end() like so:
So the operator -> would look like this: T &operator ->();
| |||
|
Last edited on
|
|||
| Volatile Pulse (1329) | |||
|
Thanks for all of your help so far. Is there any issue with being able to access those elements, for example, next, last, value, etc? Should something be changed with my iterator, node, or list classes? I also read on a stackoverflow forum that auto can select private classes, in this case node, which shouldn't be able to be accessed. Again, is this a problem? To me, I'm content with using auto in this situation since it's a pain to constantly type out vp::list<int>::iterator.One last question. When looking at the STL implementation, it refers to Allocators. From http://cplusplus.com/reference/list/list/list/
Up until now, I have just ignored the Allocator since I've never used one for any STL container. Is this something I should look into implementing in my code? or should I just ignore it? For the most part, the rest of the functions of an STL list look pretty straight forward. Obviously, I'll have to do some error testing when it comes to seeing if my definitions are correct, much like the situation with my end function. Is there anything that you see or saw in my code thus far that may cause issues down the road? Thanks again for all of your help though. Edit: Trying to switch my it type to vp::list<int>::iterator* yields this error:
That makes me assume that auto actually uses a node pointer, which again should be restricted, is irrelevant to me, but shouldn't my iterator class be convertible from a node to prevent needing a node? | |||
|
Last edited on
|
|||
| Volatile Pulse (1329) | |||
So then what would actually be getting returned? If I return current->value, I'll receive an int in this situation which isn't comparable to an iterator. I don't know what else should be returned instead of a node. Possibly an iterator reference instead? Everything so far was just to get by, now I'm running in to issues with simple implementations and I don't enjoy that. I'm getting stuck with what an iterator should be in this case. Obviously I don't want it to be a node, I don't want it to be T& either. | |||
|
|
|||
| coder777 (2377) | |||||
to make your iterator compliant to STL it looks like this;
| |||||
|
|
|||||
| Volatile Pulse (1329) | |||||
|
I must have had the wrong concept of what an iterator was then -.- Anyways, I made the above changes and I ended up with something that looks weird so I cross checked it with the STL list and it has the same affect. Looping through the list with iterators, every value has the same exact memory location. Is this right?
Also, why can't you compare an iterator with list.begin() like if (it == myList1.begin())? I get the error
I also get a very similar error with the STL lists. Why aren't iterators comparable? or am I comparing the wrong things? | |||||
|
|
|||||
| coder777 (2377) | ||
it by the way is not an iterator but the value which content is set during each iteration.What strange is, is this: it == myList1.vp::list<T>::begin<int>()where does this template parameter come from? otherwise iterators of the same type are comparable since you implement them so. | ||
|
Last edited on
|
||
| Volatile Pulse (1329) | |||
|
That was the error returned from g++ while trying to compare it and myList1.begin(). And I'm confused. Why don't we want an iterator but instead want the value? I think I'm confusing myself now, but shouldn't auto be an iterator instead of T? I'm going to have to take a look again at how everything should interact. If I understand correctly, an iterator isn't really being used by myself, but more by the compiler to traverse the list in the range. I assume the reason it returns the value is so that you can change what you need to without having access to private data. But then, are iterators the only way to traverse the list? Can pointers not be used like they are in arrays? Or instead of a pointer, something similar? In theory, shouldn't something like this work?
Or does it work, but I just need to specify an iterator instead of T when declaring 'it'. | |||
|
|
|||
| cire (1845) | |||||||
If you write:
For all practical purposes, it expands to:
Typically, the range-based for loop would be used with a reference type so you aren't making copies of each item in the list:
It is just shorthand for the longer version. | |||||||
|
Last edited on
|
|||||||