首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >addressof的实现

addressof的实现
EN

Stack Overflow用户
提问于 2013-04-24 22:46:26
回答 3查看 2.3K关注 0票数 32

以前不知道std::addressof的存在,为什么它存在对我来说很有意义:作为一种在重载的operator&存在的情况下获取地址的方式。然而,它的实现稍微有点不透明。来自gcc 4.7.1

代码语言:javascript
复制
template<typename _Tp>
inline _Tp*
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{
  return reinterpret_cast<_Tp*>
(&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
}

reinterpret_cast<_Tp*>是显而易见的。剩下的都是黑魔法。有人能分析一下这是如何实际工作的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-24 22:54:45

首先,你有一个类型为_Tp&

  • It的reinterpret_cast

  • 到一个char&,以确保以后能够获取它的地址,而不用担心在原始类型中有一个过载的operator&;实际上它被强制转换为const volatile char&,因为reinterpret_cast总是可以合法地添加constvolatile限定符,即使它们不存在,但如果它们存在,它就不能删除它们(这确保了_Tp最初拥有的任何限定符,它们都不会干扰强制转换)。

  • This is const_cast'ed to char&,删除限定符(从法律上讲,现在!对于qualifiers).

  • The地址,const_cast可以做reinterpret_cast不能做的事情)返回(现在我们有一个简单的char*)

  • It is reinterpret_cast'ed reinterpret_cast & reinterpret_cast to _Tp* (包括原始constvolatile限定符,如果有)。

编辑:由于我的回答已经被接受,我将彻底地补充说,选择char作为中间类型是由于对齐问题,以避免触发未定义的行为。查看@JamesKanze的评论(在问题下)以获得完整的解释。感谢James如此清晰地解释。

票数 32
EN

Stack Overflow用户

发布于 2013-04-24 22:56:02

简短版本:

不能为char重载operator&。因此,该类型被强制转换为char引用,以获取被保证为真实地址的内容。

由于对const_castreinterpret_cast的限制,这种转换是通过两次强制转换完成的。

更长的版本:

它正在执行三个连续的强制转换。

代码语言:javascript
复制
reinterpret_cast<const volatile char&>

这实际上是转换为char&constvolatile之所以存在,是因为_Tp可能是constvolatilereinterpret_cast可以添加它们,但无法删除它们。

代码语言:javascript
复制
const_cast<char&>

现在已经删除了constvolatileconst_cast可以做到这一点。

代码语言:javascript
复制
reinterpret_cast<_Tp*>(&result)

现在,地址被获取,类型被转换回指向原始类型的指针。

票数 10
EN

Stack Overflow用户

发布于 2013-04-24 22:56:31

从里到外:

首先,它将__r类型强制转换为const volatile char&:,它强制转换为char&,因为它的类型肯定没有重载的operator&,这样做很时髦。const volatile之所以存在,是因为这些都是限制,可以用reinterpret_cast添加,但不能删除。_Tp可能已经是const和/或volatile,在这种情况下,在此类型转换中需要一个或两者。如果没有,演员们只是不必要地添加了它们,但它是为限制最严格的演员而写的。

  • 接下来,为了去掉const volatile,你需要一个const_cast,这将导致下一部分……const_cast<char&>。从那里,

  • ,他们简单地获取地址,并将其转换为你想要的类型,一个_Tp*。请注意,_Tp可能是const和/或volatile,这意味着可以在此时将这些内容添加回去。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16195032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档