Considerations and implementation of a method to copy the vector<t>::iterator</t>
-
My title is probably not very well phrased, but here is the problem. Let's say I've got functions
a()
,b()
, wherea()
callsb()
, andb()
callsvector<T>::iterator iter = someVector.begin()
.b()
needs to pass this iterator down toa()
via avoid*
mechanism, without returning it (essentially using reference passing), so more explicitly, the two functions are:void a(void*& param);
void b(void*& param);The problem is, we can't simply do something like this:
vector<T>::iterator iter = someVector.begin();
param = reinterpret_cast<void*>(iter)This is because the compiler (MSVC9) will complain about trying to cast an iterator to a void*:
error C2440: 'reinterpret_cast' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'void *'
Likewise, I can't do something like...
vector<T>::iterator iter = someVector.begin();
param = reinterpret_cast<void*>(&iter)...because even though this will compile, it will not work because
begin()
actually returns an iterator object and not a pointer to some memory location, so the memory address of that object will go out of scope (not sure when, but I'm guessing when you leaveb()
). So, because I can't do any of this, I thought that maybe I could do a memory copy of the iterator, pass it up as a void*, and then cast it back to an iterator, so something along these lines:vector<T>::iterator iter = someVector.begin();
void* mem = malloc(sizeof(vector<T>::iterator));
//memcpy starting from &iter up to the size, into the malloc memory
param = mem;And on the flip side, in order to decode my data, I'd do something like this:
vector<T>::iterator = reinterpret_cast<vector<T>::iterator>(param);
I'm wondering whether or not this idea of mine is feasible or will cause me many problems, or if there is a better way of doing what I'd like to do, given the limitations (can only pass by void* reference). Thanks.
-
My title is probably not very well phrased, but here is the problem. Let's say I've got functions
a()
,b()
, wherea()
callsb()
, andb()
callsvector<T>::iterator iter = someVector.begin()
.b()
needs to pass this iterator down toa()
via avoid*
mechanism, without returning it (essentially using reference passing), so more explicitly, the two functions are:void a(void*& param);
void b(void*& param);The problem is, we can't simply do something like this:
vector<T>::iterator iter = someVector.begin();
param = reinterpret_cast<void*>(iter)This is because the compiler (MSVC9) will complain about trying to cast an iterator to a void*:
error C2440: 'reinterpret_cast' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'void *'
Likewise, I can't do something like...
vector<T>::iterator iter = someVector.begin();
param = reinterpret_cast<void*>(&iter)...because even though this will compile, it will not work because
begin()
actually returns an iterator object and not a pointer to some memory location, so the memory address of that object will go out of scope (not sure when, but I'm guessing when you leaveb()
). So, because I can't do any of this, I thought that maybe I could do a memory copy of the iterator, pass it up as a void*, and then cast it back to an iterator, so something along these lines:vector<T>::iterator iter = someVector.begin();
void* mem = malloc(sizeof(vector<T>::iterator));
//memcpy starting from &iter up to the size, into the malloc memory
param = mem;And on the flip side, in order to decode my data, I'd do something like this:
vector<T>::iterator = reinterpret_cast<vector<T>::iterator>(param);
I'm wondering whether or not this idea of mine is feasible or will cause me many problems, or if there is a better way of doing what I'd like to do, given the limitations (can only pass by void* reference). Thanks.
Apart from the fact you're using malloc, the last idea's OK. Use
new
instead - it's C++, man!param = reinterpret_cast<void*>(new vector<T>::iterator(someVector.begin()));
Remember to
delete
it afterwards as well....Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Apart from the fact you're using malloc, the last idea's OK. Use
new
instead - it's C++, man!param = reinterpret_cast<void*>(new vector<T>::iterator(someVector.begin()));
Remember to
delete
it afterwards as well....Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Yeah, well, the way I see it, malloc just does a simple memory allocation, whereas new also calls the parameterless constructor. In this case, since I'm overwriting everything, I figured malloc was the better way, but from my testing, it seems that new works as well. I've managed to get some sample code working, and it seems to be fine when T = int, but I've been told that it may not work where T is a more complicated class.
-
Yeah, well, the way I see it, malloc just does a simple memory allocation, whereas new also calls the parameterless constructor. In this case, since I'm overwriting everything, I figured malloc was the better way, but from my testing, it seems that new works as well. I've managed to get some sample code working, and it seems to be fine when T = int, but I've been told that it may not work where T is a more complicated class.
Should be fine, no matter what T is - an iterator generally only holds a reference to an item in a container (for simple, container iterators).
Cyrilix wrote:
new also calls the parameterless constructor
new will call whichever constructor you specify. In my example, I use teh copy constructor.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
My title is probably not very well phrased, but here is the problem. Let's say I've got functions
a()
,b()
, wherea()
callsb()
, andb()
callsvector<T>::iterator iter = someVector.begin()
.b()
needs to pass this iterator down toa()
via avoid*
mechanism, without returning it (essentially using reference passing), so more explicitly, the two functions are:void a(void*& param);
void b(void*& param);The problem is, we can't simply do something like this:
vector<T>::iterator iter = someVector.begin();
param = reinterpret_cast<void*>(iter)This is because the compiler (MSVC9) will complain about trying to cast an iterator to a void*:
error C2440: 'reinterpret_cast' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'void *'
Likewise, I can't do something like...
vector<T>::iterator iter = someVector.begin();
param = reinterpret_cast<void*>(&iter)...because even though this will compile, it will not work because
begin()
actually returns an iterator object and not a pointer to some memory location, so the memory address of that object will go out of scope (not sure when, but I'm guessing when you leaveb()
). So, because I can't do any of this, I thought that maybe I could do a memory copy of the iterator, pass it up as a void*, and then cast it back to an iterator, so something along these lines:vector<T>::iterator iter = someVector.begin();
void* mem = malloc(sizeof(vector<T>::iterator));
//memcpy starting from &iter up to the size, into the malloc memory
param = mem;And on the flip side, in order to decode my data, I'd do something like this:
vector<T>::iterator = reinterpret_cast<vector<T>::iterator>(param);
I'm wondering whether or not this idea of mine is feasible or will cause me many problems, or if there is a better way of doing what I'd like to do, given the limitations (can only pass by void* reference). Thanks.
In any recent version of VC, iterators are not simple pointers. There is some debug info kept around to detect dangling iterators and iterators that point outside of their containers. So doing a straight memcpy will work only as long as the original iterator exists. What about this:
vector::iterator* piter = new vector::iterator ( someVector.begin() );
void* pv = (void*) piter;?
Last modified: 5hrs 10mins after originally posted -- fixde tpyo
--Mike--
-
In any recent version of VC, iterators are not simple pointers. There is some debug info kept around to detect dangling iterators and iterators that point outside of their containers. So doing a straight memcpy will work only as long as the original iterator exists. What about this:
vector::iterator* piter = new vector::iterator ( someVector.begin() );
void* pv = (void*) piter;?
Last modified: 5hrs 10mins after originally posted -- fixde tpyo
--Mike--