何时使用addressof(x)而不是&x?

Meh*_*dad 60 c++ addressof

我如何决定是否需要addressof(x)而不是&x在获取对象的地址时?


似乎这个问题令人困惑,所以需要澄清:

addressof显然绕过了重载的地址运算符.我已经意识到了这一点.

我想知道的是:
我怎么知道这是不是我真的想做什么?(特别是在模板内部等)

是否有某种"规则"可以帮助我找出什么时候需要addressof而不是&
毕竟,他们都返回对象的"地址",那么我什么时候使用哪个?

Nic*_*las 82

你需要的std::addressof时候使用.可悲的是,"当你不得不"包括任何时候你在模板代码的工作,并希望把未知类型的变量TT&为一个诚实神指针变量的内存.

因为C++委员会愚蠢地允许引用运算符的重载(为了很小的合法目的),所以用户可以使用某种类型来实例化模板,而不能使用引用运算符来获取实际指针.std::addressof是一种解决使用这种可疑C++功能的用户的方法,以便完成语言应该保证开始工作的内容.

简而言之,它是一种语言愚蠢的库修复.&如果您想确保用户不会破坏您的代码,请在模板代码中使用它.如果您的用户可以信任不使用这个il-conceived功能,那么您可以使用&.

  • 我觉得有趣的是,我*期望*的*一个*类重载了`reference_wrapper`的地址,似乎并没有... (2认同)
  • @Mehrdad:这并不让我感到惊讶; `reference_wrapper`和`addressof`来自Boost.AKA:最了解超载运营商危险的人. (2认同)
  • 回顾这一点,我不确定允许重载地址操作符是否愚蠢。对于Boost.Lambda之类的东西,它代表接收地址的操作很有用。但似乎只是被滥用了。 (2认同)

Luc*_*ore 11

如果它是具有重载的一元的用户定义类型operator&,并且您想要其地址,请使用addressof.

我会说你应该总是使用,&因为正如你所说,如果你不这样做,它就会超越过载的目的.当然除非你对重载做了一些有意义的事情,在这种情况下你需要addressof(在课堂之外,在你可以使用的内部this),但是你必须非常肯定你正在做什么.

这里有更多 - 如果你想operator&在类之外重载(你可以),你必须使用addressof返回地址,否则它会导致无限递归:

struct Class
{
   virtual ~Class() {}
   int x;
};

void* operator&(const Class& x)
{
    //return &x; <---- infinite recursion
    return addressof(x) + 4; //I know this isn't safe
                             //but I also know the intrinsics of my compiler
                             //and platform to know this will actually return
                             //the address to the first data member
}
Run Code Online (Sandbox Code Playgroud)

我知道这不安全.


jua*_*nza 8

当您想知道对象的实际地址时,请使用它,而不是operator&过载地址的结果.

  • @Mehrdad:"*难道不会失败运算符重载的目的吗?*"你说这就像以为*曾经*超载该运算符的合理理由.`std :: addressof`存在是因为C++标准委员会搞砸了. (2认同)

Ben*_*ley 7

我的意见只有:

除非您是设计该类及其界面的团队的一员,否则永远不会.我个人从来没有看到过重运算符的充分理由.但是如果有人设计了一个有意义的类,并假设该类是为了公共消费(也就是说,该类不仅仅是在特定的库中内部使用),我希望该类能够在普通代码中工作自然希望这&意味着"地址".如果重载运算符的类不是以这种合理的方式设计的,那么我就不会使用那个类,句点.因为该类被破坏了,或者它不打算在它所属的库之外使用.


Jon*_*ely 6

毕竟,他们都返回对象的"地址",那么我什么时候使用哪个?

你绝对不能保证重载operator&是对象的"地址",很可能不是,或者类作者可能不会为了超载它而烦恼.void如果他们不明智地试图阻止人们取其地址,他们可能会超载它以返回不同类型,甚至返回.

如果你想要一个指向可能已经重载的对象的指针&(例如,因为它的类型是模板参数,所以你不知道)然后使用std::addressof或记录你的模板不支持不返回对象的真实地址的类型作为正确的类型.