【问题标题】:Most portable and reliable way to get the address of variable in C++在 C++ 中获取变量地址的最便携和可靠的方法
【发布时间】: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&amp;() 重载时才能正常工作。所以如果我打电话给tryProcess&lt;_com_ptr_&lt;Interface&gt;&gt;(),我会得到意想不到的结果——触发了重载的operator&amp;()

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&amp;() 重载,都将始终获得相同的行为。这在 Visual C++ 7 上通过优化引入了零开销 - 编译器知道要做什么,只获取对象地址。

此问题的解决方案的可移植性和标准兼容性如何?如何改进?

【问题讨论】:

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


【解决方案1】:

Boost addressof 是使用 reinterpret_cast 技巧实现的,所以我想说它可能是可移植的且符合标准的。

Here你可以看到有问题的代码。

【讨论】:

【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 2018-03-19
    • 2011-01-26
    • 2011-08-12
    • 2013-04-23
    • 1970-01-01
    • 2011-06-15
    • 2010-12-25
    • 2010-11-11
    相关资源
    最近更新 更多