【发布时间】:2011-01-20 22:59:05
【问题描述】:
如果变量类型已重载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 上通过优化引入了零开销 - 编译器知道要做什么,只获取对象地址。
此问题的解决方案的可移植性和标准兼容性如何?如何改进?
【问题讨论】:
-
供以后的读者参考:C++11标准化了这个成语的一个整齐包装(以前
boost)的版本,如std::addressof:en.cppreference.com/w/cpp/memory/addressof`
标签: c++ visual-c++ casting