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

时间:2010-02-25 10:43:51

标签: c++ visual-c++ casting

如果变量类型已超载&,则使用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&()

another question中,以下解决方法为suggested

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 个答案:

答案 0 :(得分:4)

Boost addressof是使用reinterpret_cast技巧实现的,所以我说它可能是便携式和符合标准的。

Here您可以看到相关代码。

答案 1 :(得分:3)

这是标准投诉。这个问题引起了ISO C ++委员会的注意,涉及offsetof实现的问题。考虑的解决方案包括收紧POD定义,或对offsetof使用的类型添加额外限制。当提出reinterpret_cast解决方案时,这些解决方案被拒绝了。由于这提供了一个符合标准的方法来解决问题,委员会认为没有必要为offsetof添加额外的需求,并且修复了实现。