Использование &
для получения адреса переменной может быть проблематичным, если тип переменной перегружен operator&()
. Например, _ com_ptr_ имеет operator&()
перегружен побочным эффектом изменения объекта.
Теперь у меня есть сложный набор шаблонов с такими функциями:
template<class T>
void process( const T* object )
{
//whatever
}
template<class T>
void tryProcess( T& object )
{
process( &object )
}
В tryProcess()
мне нужно получить указатель T*
, содержащий адрес фактического объекта типа T
.
Вышеупомянутая реализация tryProcess()
будет работать только в том случае, если class T
не имеет перегруженного operator&()
. Поэтому, если я вызываю tryProcess<_com_ptr_<Interface>>()
, я могу получить неожиданные результаты - срабатывает перегруженный operator&()
.
В другом вопросе следующее обходное решение :
template<class T>
T* getAddress( T& object )
{
return reinterpret_cast<T*>( &reinterpret_cast<char&>( object ) );
}
С такой функцией я могу реализовать tryProcess()
следующим образом:
template<class T>
void tryProcess( T& object )
{
process( getAddress( object ) )
}
и всегда будет получать одно и то же поведение независимо от того, перегружен ли class T
operator&()
. Это вводит нулевые накладные расходы с оптимизацией на Visual С++ 7 - компилятор получает то, что нужно делать, и просто получает адрес объекта.
Насколько переносимым и стандартным компилятором является это решение проблемы? Как это можно улучшить?