resueltos - La forma más portátil y confiable de obtener la dirección de la variable en C++
punteros en c (2)
Usar &
para obtener una dirección de una variable puede ser problemático si el tipo de variable ha sobrecargado el operator&()
. Por ejemplo, _com_ptr_ tiene operator&()
sobrecargado con un efecto secundario de modificar el objeto.
Ahora tengo un conjunto complicado de plantillas con funciones como esta:
template<class T>
void process( const T* object )
{
//whatever
}
template<class T>
void tryProcess( T& object )
{
process( &object )
}
En tryProcess()
necesito obtener un puntero T*
contenga la dirección del objeto real de tipo T
La implementación anterior de tryProcess()
solo funcionará correctamente si la class T
no tiene operator&()
sobrecargado. Entonces, si llamo tryProcess<_com_ptr_<Interface>>()
, puedo obtener resultados inesperados: se activa el operator&()
sobrecargado operator&()
.
En otra pregunta, se sugiere la siguiente solución:
template<class T>
T* getAddress( T& object )
{
return reinterpret_cast<T*>( &reinterpret_cast<char&>( object ) );
}
Con tal función puedo implementar tryProcess()
siguiente manera:
template<class T>
void tryProcess( T& object )
{
process( getAddress( object ) )
}
y siempre obtendrá el mismo comportamiento independientemente de si la class T
tiene operator&()
sobrecargado. Esto introduce una sobrecarga cero con optimizaciones en Visual C ++ 7: el compilador obtiene qué hacer y solo obtiene la dirección del objeto.
¿Qué tan portátil y estándar compilant es esta solución al problema? ¿Cómo puede ser mejorado?
Boost addressof
se implementa con ese truco de reinterpret_cast
así que diría que probablemente sea portátil y de conformidad estándar.
Aquí puedes ver el código en cuestión.
Es una queja estándar. El problema se señaló a la atención del comité de ISO C ++ en relación con los problemas con la offsetof
implementaciones que se rompieron en esto. Entre las soluciones consideradas estaban ajustar la definición de POD o agregar una restricción adicional a los tipos que se usarían con offsetof
. Esas soluciones fueron rechazadas cuando se presentó la solución reinterpret_cast
. Dado que esto ofrecía una manera de cumplir con el estándar en torno al problema, el comité no vio la necesidad de agregar requisitos adicionales al offsetof
y dejó correcciones a las implementaciones.