如果变量类型已超载&
,则使用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上进行优化的零开销 - 编译器获取要做的事情并获取对象地址。
这个问题的解决方案如何便携和标准兼容?怎么可以改进?
答案 0 :(得分:4)
Boost addressof
是使用reinterpret_cast
技巧实现的,所以我说它可能是便携式和符合标准的。
Here您可以看到相关代码。
答案 1 :(得分:3)
这是标准投诉。这个问题引起了ISO C ++委员会的注意,涉及offsetof
实现的问题。考虑的解决方案包括收紧POD定义,或对offsetof
使用的类型添加额外限制。当提出reinterpret_cast
解决方案时,这些解决方案被拒绝了。由于这提供了一个符合标准的方法来解决问题,委员会认为没有必要为offsetof
添加额外的需求,并且修复了实现。