views:

165

answers:

2

Using & to get an address of a variable can be problematic if the variable type has overloaded operator&(). For example, _com_ptr_ has operator&() overloaded with a side effect of modifying the object.

Now I have a complicated set of templates with functions like this:

template<class T>
void process( const T* object )
{
    //whatever
}    

template<class T>
void tryProcess( T& object )
{
    process( &object )
}

In tryProcess() I need to get a T* pointer holding the address of the actual object of type T.

The above implementation of tryProcess() will only work allright if class T doesn't have operator&() overloaded. So if I call tryProcess<_com_ptr_<Interface>>() I can get unexpected results - the overloaded operator&() is triggered.

In another question the following workaround is suggested:

template<class T>
T* getAddress( T& object )
{
   return reinterpret_cast<T*>( &reinterpret_cast<char&>( object ) );
}

With such a function I can implement tryProcess() as follows:

template<class T>
void tryProcess( T& object )
{
    process( getAddress( object ) )
}

and will always get the same behavior independent of whether class T has operator&() overloaded. This introduces zero overhead with optimizations on on Visual C++ 7 - the compiler gets what to do and just gets the object address.

How portable and standard-compilant is this solution to the problem? How could it be improved?

+4  A: 

Boost addressof is implemented with that reinterpret_cast trick so I'd say it's probably portable and standard-conforming.

Here you can see the code in question.

Manuel
+3  A: 

It is standard-complaint. The issue was brought to the attention of the ISO C++ committee in relation to problems with offset_of implementations that broke on this. Amongst the solutions considered were tightening the POD definition, or adding an extra restriction on types to be used with offset_of. Those solutions were rejected when the reinterpret_cast solution was brought up. Since this offered a standard-compliant way around the problem, the committee did not see a need to add extra requirements to the offset_of, and left fixes to the implementations.

MSalters