Alright, so here's the situation. I have a std::vector<Class>::iterator. I have a member of the same class type, that is a pointer. If I understand interators right, they are just pointers. So, could I just make that member equal to the iterator?
The STL iterators are not convertible to their corresponding pointer types. Therefore, std::vector<int>::iterator is the type you're trying to assign, which of course, isn't going to happen. However, there's a workaround to this. On GCC, iterators have a secret member function called base() it obtains the internal pointer. Here's an example:
Iter is an iterator, not an Enemy pointer (I guess). Don't know much about it, but iterators seem a little more complex than just a pointer being incremented.
You deference the iterator to get the value: *iter, but then you still need to reference the memory location of the value &(*iter).
Is there documentation on this hidden function anywhere? And I assume it's not a standard thing?
From readability, I'd say the way I ended up using is better. Is there a performance increase to using the base() function? I am going to be needing to do this operation pretty often.
Using iterators will make them more coupled (to the container were they are).
If you will use vector I suggest to keep an index instead, as the iterators and pointers can be easy invalidated.
target = &(*iter);
An iterator is not a pointer. It's an structure used to traverse a container in a opaque way.
So when dereferencing an iterator you obtain the object, and then you get the memory address of the object. But the operations are not inverse of each other.
I guess that you could just
1 2 3
class vector{
public:
typedef T* iterator;
but you could make it ``safer'' by using a wrapper instead.
I wasn't really wanting to use indices. Could I just set the initial capacity of the vector to a size large enough that it won't need to resize?
EDIT:
Well, after reading docs on it, looks like this will do exactly what I want.
Does seem to add just another thing that can cause an error down the road though.
"Is there documentation on this hidden function anywhere? And I assume it's not a standard thing? "
Not that I know of. I found the function by digging through the std::__normal_iterator implementation. I looked at its definition and the only thing it does is return the internal pointer. Since it's an in-line, one-liner function, it won't slow down the program, but it will increase the amount of CPU cache hits. Be wary, though, because too much in-lining can cause an increase in CPU cache misses, an increase in object code, and can cause thrashing.
Looks like it returns _Iterator _M_current, which I can't seem to find the initialization of. This code is definitely not recreational reading haha.
Anyway, the only thing that concerns me is the potential increased cache misses. Pretty much out of everything in the program, this would be the most performance dependent.
It's a pointer declaration which is initialised with a call to base_of_pointer(). The type between base_of_pointer and the parentheses is used to deduce the type the iterator points to, because the compiler will not be able to deduce it. iterator_ is then passed to it.
Here's where the pre-processor directives come in. If MICROSOFT_COMPILER was defined, the _Ptr member of std::vector::iterator is returned. If GCC_COMPILER is defined, the base() member function of std::vector::iterator is called instead, and the pointer it returns, is returned from base_of_iterator().
int *pointer = (base_of_iterator<int>(iterator_));
Why can't you just do that?
And I understand template right (which I have barely messed with),
base_of_iterator<int>(iterator_) this is just a function call, with the <int> specifying the data type to be used, and iterator_ is the actual argument?
I guess you could initialise pointer in that way, but I pref the functional notation; personal preference, of course.
ResidentBiscuit wrote:
base_of_iterator<int>(iterator_)"this is just a function call, with the <int> specifying the data type to be used, and iterator_ is the actual argument?"
That's right. Note that iterator_ wasn't passed by reference because the underlying type is a primitive, and therefore, would likely incur a performance penalty.
Oooh I forgot all about assigning variables with functional notation. I remember seeing something for it a long time ago and brushed it off to the side as unimportant. Just looked it up and sparked my memory.
Now I thought with templates, you could just call the function normally, and the compiler would examine the arguments, and set a type accordingly?
Sometimes the compiler is able to deduce the type based on the arguments, but not in this case because std::vector::iterator is the parameter type, and int is the underlying type of the iterator class.