大多数可移植且可靠的方法来获取C++中的变量地址

sha*_*oth 6 c++ casting visual-c++

使用&如果变量类型已超载获取变量的地址可能会有问题operator&().例如,_com_ptr_已经operator&()重载,具有修改对象的副作用.

现在我有一组复杂的模板,其功能如下:

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

template<class T>
void tryProcess( T& object )
{
    process( &object )
}
Run Code Online (Sandbox Code Playgroud)

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 ) );
}
Run Code Online (Sandbox Code Playgroud)

有了这样的功能,我可以实现tryProcess()如下:

template<class T>
void tryProcess( T& object )
{
    process( getAddress( object ) )
}
Run Code Online (Sandbox Code Playgroud)

并且将始终获得相同的行为,而不管是否class Toperator&()超载.这引入了在Visual C++ 7上进行优化的零开销 - 编译器获取要做的事情并获取对象地址.

这个问题的解决方案如何便携和标准兼容?怎么可以改进?

MSa*_*ers 3

这是标准投诉。该问题已引起 ISO C++ 委员会的注意,因为offsetof该问题与实现中出现的问题有关。考虑的解决方案包括收紧 POD 定义,或对与 一起使用的类型添加额外的限制offsetofreinterpret_cast当提出解决方案时,这些解决方案被拒绝了。由于这提供了一种解决该问题的符合标准的方法,因此委员会认为没有必要向 中添加额外的要求offsetof,并留下了对实现的修复。