iter to address of item

Started by
22 comments, last by MaulingMonkey 16 years ago
Quote:Original post by SpreeTree
I don't know if "you can save a lot of time in the future when you start trying to treat an iterator as you would a pointer" was clear enough, but I meant you can save yourself time by knowing exactly why treating an iterator like a pointer causes errors, rather then trying to use it as one and not knowing why it doesn't work.

Considering that the statement has nothing to do with what you say it means, then it probably isn't clear enough. Re-read that sentence a few times. You said that using treating an iterator like a pointer saves time, which, as I said, contradicts your argument. It says nothing about understanding why treating an iterator as a pointer would cause errors. It instead says that treating an iterator as a pointer is beneficial.

Quote:Would I dereference a vector<MyObject**>::iterator. To right I would. I'd much rather use the basic type (MyObject**) as I assume I know what that is, know how it works and understand the context in which I am using it.

Not what I asked, especially given that using -> on a vector<MyObject **>::iterator would be invalid. I asked if you would always dereference normal pointers, since that makes your code that uses double pointers the same as the code that uses normal pointers. Since you think that the existence of vector<MyObject*>::iterator justifies always dereferencing vector<MyObject>::iterators before using them, applying the same logic to pointers means that you would never use -> on a MyObject * since you can't use -> on a MyObject **.

Quote:
Personally I would call do_something(*(my_vector.begin()+7)) and pass it by reference for two reasons

But you're still doing random access iterator arithmetic on the iterator, which is something you can do on normal pointers, which by your logic makes you think of iterators like pointers, so you should never do.

Quote:But by being able to use iterators as pointers (by being able to use operator->),

Using -> isn't using an iterator as a pointer, it's using an iterator as an iterator.

Unless you want to say that any valid operation on an iterator that is also a valid operation on a pointer is using an iterator like a pointer. In which case there is absolutely no operation on an iterator that isn't also using an iterator as a pointer. Even dereferencing an iterator like you suggest would be using an iterator like a pointer.

Quote:You are talking about the implementation details of the STL,

And where do you see any implementation details in my posts? I'm talking about the use of STL, and the inconsistency of your arguments for not using iterator functionality. A brief perusal of this thread shows the only implementation detail mentioned would actually have been brought up by you, with your alleged STL implementation that doesn't support -> on container iterators.
Advertisement
Quote:Original post by SiCrane
Considering that the statement has nothing to do with what you say it means, then it probably isn't clear enough. Re-read that sentence a few times. You said that using treating an iterator like a pointer saves time, which, as I said, contradicts your argument.


While I can accept the sentence could have been taken further (to detail exactly what I meant), I think I have cleared that up though but for some reason you don't seem happy with that (to try and make that obvious, I have edited the original post).


Quote:Original post by SiCrane
Not what I asked


Okay, to answer what you actually asked (I think we are both misunderstanding each other here), no I wouldn't, but I am specifically talking about the use of iterators. Raw pointers declared as raw pointers are totally different, and I can't belive you are using that as an argument.


Quote:Original post by SiCrane
Since you think that the existence of vector<MyObject*>::iterator justifies always dereferencing vector<MyObject>::iterators before using them, applying the same logic to pointers means that you would never use -> on a MyObject * since you can't use -> on a MyObject **.


Using that as justification is not what I have been doing at all, I used it as an example of consistency. For consistency (and clarity), in my example you are always using the base type. To use the iterators as they come, you need to know that vector<MyObject*>::iterator is a MyObject**. Many people have issues with pointers as it is, let alone them having to use **.


Quote:Original post by SiCrane
But you're still doing random access iterator arithmetic on the iterator, which is something you can do on normal pointers, which by your logic makes you think of iterators like pointers, so you should never do.


I can also use operator+ on integers, but that doesn't make me think iterators are ints does it. Using operator-> is a more specific case that most people will use specifically for pointers, and that is the point I am trying to make.

I would also expect someone with less experience of the STL (which is the people I am specifically talking about) to use my_vector[7], which returns a reference anyway.


Quote:Original post by SiCrane
Even dereferencing an iterator like you suggest would be using an iterator like a pointer.


Indeed, and in some cases I would say that was a mis-design on the part of the STL specification. It would be nice to have an option of dereferencing an iterator using an STL specific operation, rather than operator*. I am saying that being able to use ALL pointer operators on iterators can lead down a rough road, which it can.

Quote:Original post by SiCrane
with your alleged STL implementation that doesn't support -> on container iterators.


Alleged... You're obviously not going to be happy with any explanation I make on this one, but hey, that’s how it is.


I'm sorry you keep saying my arguments are not consistent, but I have said the same thing in many different ways, taking it from a specific outlook (that of the inexperienced user of STL). Personally I think you are picking holes in an argument that isn't there. I fully understand that iterators can be used like pointers, I just don't agree that in all cases they should be. Unfortunately, you don't seem to want to see where I am coming from regardless of how it put it - and this could go on all night, which I rather it didn't :)
Quote:Original post by SpreeTree
Okay, to answer what you actually asked (I think we are both misunderstanding each other here), no I wouldn't, but I am specifically talking about the use of iterators. Raw pointers declared as raw pointers are totally different, and I can't belive you are using that as an argument.

Totally different? Iterators share the exact same syntax, because that's how iterators are designed.

Quote:Using that as justification is not what I have been doing at all, I used it as an example of consistency.

No, that's one of the things you listed as one of your justifications. You even quoted yourself on it:
Quote:
getting into a habit of dereferencing an iterator makes it easier to use things like vector<MyObject*>::iterator, as you then have a more consistent code base when it comes to the STL.

Remember that post where you quoted yourself three times and said those were the three reasons you think you should always dereference iterators? It wasn't that long ago.

Quote: For consistency (and clarity), in my example you are always using the base type. To use the iterators as they come, you need to know that vector<MyObject*>::iterator is a MyObject**. Many people have issues with pointers as it is, let alone them having to use **.

So why not for consistency (and clarity) would you not always use the base type of the pointer? Since you think pointers are so difficult then why do you think that you shouldn't always dereference a normal pointer to create a more consistent code base when it comes to pointers? You seem to think iterators are so difficult it's important to create a consistent code base when it comes to iterators.

Quote:Original post by SiCrane
Using operator-> is a more specific case that most people will use specifically for pointers, and that is the point I am trying to make.

So would you also tell people to always dereference a boost::shared_ptr<> or a std::auto_ptr<> before using them? After all, both of them use operator -> and you can't static_cast either of those to a pointer type either.

Quote:I would also expect someone with less experience of the STL (which is the people I am specifically talking about) to use my_vector[7], which returns a reference anyway.

And it wouldn't compile with a function that accepts either a pointer or iterator, so I fail to see how pointer/iterator confusion would apply here.

Quote:Indeed, and in some cases I would say that was a mis-design on the part of the STL specification. It would be nice to have an option of dereferencing an iterator using an STL specific operation, rather than operator*.

You have that option:
template <typename T>typename std::iterator_traits<T>::value_type STL_dereference(T iter) {  return *iter;}



Quote:Alleged... You're obviously not going to be happy with any explanation I make on this one, but hey, that’s how it is.

Any iterator class that has a functioning operator*, has a one liner implementation of operator-> : return &**this;. The chances of anyone managing to screw this up, and still produce anything even in the neighborhood of an otherwise functional STL implementation, are so low as to be laughable. Compare that to the probability that someone who doesn't seem like they really know what they're talking about making up an fictional non-compliant STL implementation that supports their argument while at the same time being conveniently unmentionable due to NDA.... So yes, alleged.
Quote:Original post by SpreeTree
... using is [*it, operator->] can lead people to believe that vector<>::iterator is a pointer when in-fact it is not.

... except when it is, as has been done, as pointers are legitimate iterators and vector's contiguity allows them to suffice.

I'll make it short: It's my experience that f( a->b->c, d->e->f ) is clearer than f( (*(*a).b).c, (*(*d).e).f ), having spent insufficient time playing with Matryoshka Dolls or LISP to sufficiently damage by brain.

Given the cost to readability, I'd much rather:
1) Give my fellow coder a clue (pointers are iterators, and that's not hard to explain!)
2) Submit the 1-liner bug fix (for those iterators missing the required operator->s!)
3) Completely ignore the addled reasoning behind arbitrary distinctions between pointers and other random access iterators and their ancestors and "Pretend" that pointers are just another iterator type.

This topic is closed to new replies.

Advertisement