std::addressof的实现
标准库中有一个std::addressof, 这个东西存在的目的是当存在operator&的重载时, 依然能够获得变量的地址. gcc(4.7.1)下的实现如下:
template<typename __Tp>
inline __Tp* __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{
return reinterpret_cast<__Tp*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
}
怎么理解
__r的类型为__Tp- 将
__r转为const volatile char&有几个作用- 防止后面用&操作符获取地址时出发原类型(即
__Tp)的重载操作(operator&). reinterpret_cast操作符总是可以合法的在原类型的基础上加const或volatile, 但是如果__Tp原来带有const或volatile的话, 通过reinterpret_cast去掉是不允许的, 因此需要加上const volatile来避免编译器报错, 也就是不用在管__Tp是否是const或volatile了.- 转换为char&, 因为换成其他类型有可能回触发强制地址对齐的操作, 这样的话真实地址就可能会改变, 造成Undefined Behavior.
- 防止后面用&操作符获取地址时出发原类型(即
const_cast将const或volatile去掉. 因为后面我们要将获取的地址转换回__Tp*, 如果__Tp原来不包含const, 因为我们前面加了const, 非const转const是不合法的, 所以这里我们在去掉. 请和第2条对着看.- 通过取地址符&获取地址后, 再通过
reinterpret_cast转换回__Tp*(回保留__Tp的const或volatile如果它有这个修饰符的话)
本文详细解析了C++标准库中的std::addressof函数模板的实现原理,阐述了其如何在存在重载运算符&的情况下,仍能正确获取变量地址。通过gcc 4.7.1版本下的具体实现代码,解释了reinterpret_cast和const_cast操作符的使用目的,以及为何需要转换为char&类型。

38

被折叠的 条评论
为什么被折叠?



