Reputation: 23091
I've got an iterator of Things. If I want to convert the current item to a pointer to the item, why does this work:
thing_pointer = &(*it);
But this not:
thing_pointer = reinterpret_cast<Thing*>(it);
This is the compiler error I'm trying to comprehend: http://msdn.microsoft.com/en-us/library/sy5tsf8z(v=vs.90).aspx
Just in case, the type of the iterator is std::_Vector_iterator<std::_Vector_val<Thing,std::allocator<Thing> > >
Upvotes: 6
Views: 2192
Reputation: 101456
Obligitory Standard Quotes, emphasis mine:
1/ [...] Conversions that can be performed explicitly using reinterpret_cast are listed below. No other conversion can be performed explicitly using reinterpret_cast.
4/ A pointer can be explicitly converted to any integral type large enough to hold it. [...]
5/ A value of integral type or enumeration type can be explicitly converted to a pointer. [...]
6/ A function pointer can be explicitly converted to a function pointer of a different type. [...]
7/ An object pointer can be explicitly converted to an object pointer of a different type. [...]
8/ Converting a function pointer to an object pointer type or vice versa is conditionally-supported. [...]
9/ The null pointer value (4.10) is converted to the null pointer value of the destination type. [...]
10/ [...] “pointer to member of X of type T1” can be explicitly converted to [...] “pointer to member of Y of type T2” [...]
11/ A [...] T1 can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. [...]
With the exception of the integral-to-pointer and value-to-reference conversions noted in 4/, 5/ and 11/ the only conversions that can be performed using reinterpret_cast
are pointer-to-pointer conversions.
However in:
thing_pointer = reinterpret_cast<Thing*>(it);
it
is not a pointer, but an object. It just so happens that this object was designed to emulate a pointer in many ways, but it's still not a pointer.
Upvotes: 3
Reputation: 254431
The first gets a reference to the object, then takes the address of it, giving the pointer.
The second tries to cast the iterator to a pointer, which is likely to fail because most types can't be cast to pointers - only other pointers, integers, and class types with a conversion operator.
Upvotes: 3
Reputation: 51226
In
&(*it);
the *
is overloaded to do what you logically mean: convert the iterator type to its pointed-to object. You can then safely take the address of this object.
Whereas in
reinterpret_cast<Thing*>(it);
you are telling the compiler to literally reinterpret the it
object as a pointer. But it might not be a pointer at all -- it might be a 50-byte struct, for all you know! In that case, the first sizeof (Thing*)
bytes of it will absolutely not happen to point at anything sensible.
Tip: reinterpret_cast<>
is nearly always the wrong thing.
Upvotes: 12
Reputation: 3423
Because iterator is not a pointer. It is a class of implementation-defined structure, and if you try to reinterpret it to a pointer, the raw data of the iterator class will be taken as a memory pointer, which may, but probably will not point to valid memory
Upvotes: 2
Reputation: 1526
*
operator of iterator is overloaded and it return a
reference to the object it points on.thing_pointer = *(reinterpret_cast<Thing**>(&it));
. But it's undefined behavior.Upvotes: 2