Большая часть портативного и надежного способа получить адрес переменной в C++

Используя & получить адрес переменной может быть проблематичным, если тип переменной перегрузился operator&(). Например, _com_ptr_ имеет operator&() перегруженный с побочным эффектом изменения объекта.

Теперь у меня есть сложный набор шаблонов с функциями как это:

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

template
void tryProcess( T& object )
{
    process( &object )
}

В tryProcess() Я должен получить a T* указатель, содержащий адрес фактического объекта типа T.

Вышеупомянутая реализация tryProcess() будет только работать хорошо если class T не имеет operator&() перегруженный. Таким образом, если я звоню tryProcess<_com_ptr_>() Я могу получить неожиданные результаты - перегруженное operator&() инициирован.

В другом вопросе предлагается следующее обходное решение:

template
T* getAddress( T& object )
{
   return reinterpret_cast( &reinterpret_cast( object ) );
}

С такой функцией я могу реализовать tryProcess() следующим образом:

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

и будет всегда получать то же поведение, независимое от ли class T имеет operator&() перегруженный. Это начинает нуль наверху с оптимизации на на Visual C++ 7 - компилятор добирается, что сделать и просто получает объектный адрес.

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

6
задан Community 23 May 2017 в 11:53
поделиться

2 ответа

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

3
ответ дан 17 December 2019 в 00:08
поделиться

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

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

4
ответ дан 17 December 2019 в 00:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: