Самый переносимый и надежный способ получить адрес переменной в C ++ - PullRequest
6 голосов
/ 25 февраля 2010

Использование & для получения адреса переменной может быть проблематичным, если тип переменной перегружен 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 ]

4 голосов
/ 25 февраля 2010

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

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

3 голосов
/ 25 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...