Самый переносимый и надежный способ получить адрес переменной в C++

С помощью & получить адрес переменной может быть проблематично, если тип переменной перегружен 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 C++ 7 - компилятор получает то, что нужно сделать, и просто получает адрес объекта.

Насколько портативным и стандартно-совместимым является это решение проблемы? Как это можно улучшить?

2 ответа

Решение

Это стандартная жалоба. Вопрос был доведен до сведения комитета ISO C++ в связи с проблемами с offsetof реализации, которые сломались на этом. Среди рассмотренных решений было ужесточение определения POD или добавление дополнительного ограничения на типы, которые будут использоваться с offsetof, Эти решения были отклонены, когда reinterpret_cast Решение было вынесено. Поскольку это предлагало совместимое со стандартами решение проблемы, комитет не видел необходимости добавлять дополнительные требования к offsetofи оставил исправления для реализаций.

Увеличениеaddressof реализуется с этим reinterpret_cast трюк, так что я бы сказал, что он, вероятно, портативный и соответствует стандартам.

Здесь вы можете увидеть рассматриваемый код.

Другие вопросы по тегам