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> > >

有帮助吗?

解决方案

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.

其他提示

Obligitory Standard Quotes, emphasis mine:

5.2.19 Reinterpret cast

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.

  1. Because * operator of iterator is overloaded and it return a reference to the object it points on.
  2. You can force it by thing_pointer = *(reinterpret_cast<Thing**>(&it));. But it's undefined behavior.

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

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top