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如果它有这个修饰符的话)