什么时候用addressof(x)而不是&x?

时间:2021-08-26 11:49:22

How do I decide whether I need addressof(x) instead of &x when taking the address of an object?

当我取一个对象的地址时,我如何决定我是否需要地址(x)而不是&x ?


Seems like the question was confusing, so a clarification is in order:

这个问题似乎让人困惑,所以有必要澄清一下:

addressof obviously bypasses the overloaded address-of operator. I'm already aware of that.

地址显然绕过了重载的操作符的地址。我已经知道了。

What I want to know is:
How do I know if that's what I really want to do? (Especially when inside a template, etc.)

我想知道的是:我怎么知道这是否是我真正想做的?(尤其是在模板内)

Is there some kind of "rule" that helps me figure out when I need addressof instead of &?
After all, they both return the "address of" the object, so when do I use which?

是否存在某种“规则”,可以帮助我确定何时需要addressof而不是&?毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?

5 个解决方案

#1


59  

You use std::addressof when you have to. Sadly, "when you have to" includes anytime you are working in template code and want to turn a variable of unknown type T or T& into an honest-to-God pointer to that variable's memory.

必须使用std::addressof。遗憾的是,“when you have to”包含了在使用模板代码的任何时候,并希望将未知类型T或T&的变量转换为指向该变量内存的真正的指针。

Because the C++ committee foolishly allowed the overloading of the reference operator (to little legitimate purpose), it is possible for a user to instantiate your template with some type that you can't use the reference operator to get an actual pointer to. std::addressof is a way to work around users who use this dubious C++ feature in order to do what the language should have guaranteed to work to begin with.

因为c++委员会愚蠢地允许对引用操作符进行重载(几乎没有合理的目的),所以用户可以用某种类型实例化模板,而您不能使用引用操作符来获得指向的实际指针。:addressof是一种与使用这个可疑的c++特性的用户打交道的方法,目的是完成语言应该保证的工作。

In short, it's a library fix for a language stupidity. Use it in template code instead of & if you want to make sure users can't break your code. If your users can be trusted not to use this il-conceived feature, then you can use &.

简而言之,这是对语言愚蠢的图书馆修正。使用模板代码而不是&如果你想确保用户不能破坏你的代码。如果您的用户可以信任不使用这个由il设计的特性,那么您可以使用&。

#2


7  

If it's a user-defined type with overloaded unary operator&, and you want its address, use addressof.

如果它是一个用户定义类型,并且有重载的unary operator&,并且您想要它的地址,使用addressof。

I'd say you should always use & because, as you say, if you don't, it defeats the purpose of the overload. Unless of course you do something meaningful with the overload, in which case you'd need addressof (outside the class, inside you can just use this), but you have to be very certain of what you're doing.

我认为你应该经常使用&因为,就像你说的,如果你不使用,它就会破坏超负荷的目的。当然,除非你在超负荷的情况下做了一些有意义的事情,在这种情况下你需要(在课堂之外,你可以使用这个),但是你必须非常确定你在做什么。

Here's more - if you want to overload operator& outside the class (you can), you have to use addressof to return the address, otherwise it results in infinite recursion:

如果你想重载operatorandoutside类(你可以),你必须使用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
}

I know this isn't safe.

我知道这不安全。

#3


6  

My opinion only:

我认为只有:

Unless you are part of the team designing the class and its interface, never. I've personally never seen a good reason to overload that operator. But if someone designs a class where it makes sense, and assuming the class is meant for public consumption(that is to say, the class is not for internal use only in a particular library), I will expect the class to work in normal code that naturally expects that & means "address of". If the class that overloads the operator isn't designed in such a sensible way, then I wouldn't use that class, period. Because either that class is broken, or it is not meant to be used outside the library which it is a part of.

除非您是设计类及其接口的团队的一员,否则永远不要这样做。我个人从未见过有什么好理由让那个操作者超负荷工作。但是如果有人设计一个类,它是有意义的,并假设类是对公共消费(也就是说,类不是仅供内部使用在一个特定的库),我将期待类工作在正常代码,自然希望&意味着“地址”。如果重载操作符的类不是以如此合理的方式设计的,那么我就不会使用那个类,句号。因为要么这个类被破坏了,要么它不打算在它所在的库之外使用。

#4


5  

Use it when you want to know the actual address of the object, and not the result of an address-of operator& overload.

当您希望知道对象的实际地址,而不是操作数和重载的地址的结果时,请使用它。

#5


4  

After all, they both return the "address of" the object, so when do I use which?

毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?

You have absolutely no guarantee that an overloaded operator& is the "address of" the object, chances are it isn't, or the class author probably wouldn't have bothered to overload it. They could have overloaded it to return a different type, or even to return void if they are ill-advisedly trying to prevent people taking its address.

您绝对不能保证重载操作符&是对象的“地址”,很可能它不是,或者类作者可能不会费心重载它。如果他们不明智地试图阻止人们使用它的地址,他们可能会让它返回另一种类型,甚至返回void。

If you want a pointer to an object which might have overloaded & (e.g. because its type is a template parameter so you don't know) then either use std::addressof or document that your template doesn't support types which don't return the object's real address as the right type.

如果您想要一个指向一个对象的指针,该对象可能已经重载了&(例如,因为它的类型是一个模板参数,所以您不知道),那么您可以使用std::addressof或文档,您的模板不支持不返回对象真实地址的类型作为正确的类型。

#1


59  

You use std::addressof when you have to. Sadly, "when you have to" includes anytime you are working in template code and want to turn a variable of unknown type T or T& into an honest-to-God pointer to that variable's memory.

必须使用std::addressof。遗憾的是,“when you have to”包含了在使用模板代码的任何时候,并希望将未知类型T或T&的变量转换为指向该变量内存的真正的指针。

Because the C++ committee foolishly allowed the overloading of the reference operator (to little legitimate purpose), it is possible for a user to instantiate your template with some type that you can't use the reference operator to get an actual pointer to. std::addressof is a way to work around users who use this dubious C++ feature in order to do what the language should have guaranteed to work to begin with.

因为c++委员会愚蠢地允许对引用操作符进行重载(几乎没有合理的目的),所以用户可以用某种类型实例化模板,而您不能使用引用操作符来获得指向的实际指针。:addressof是一种与使用这个可疑的c++特性的用户打交道的方法,目的是完成语言应该保证的工作。

In short, it's a library fix for a language stupidity. Use it in template code instead of & if you want to make sure users can't break your code. If your users can be trusted not to use this il-conceived feature, then you can use &.

简而言之,这是对语言愚蠢的图书馆修正。使用模板代码而不是&如果你想确保用户不能破坏你的代码。如果您的用户可以信任不使用这个由il设计的特性,那么您可以使用&。

#2


7  

If it's a user-defined type with overloaded unary operator&, and you want its address, use addressof.

如果它是一个用户定义类型,并且有重载的unary operator&,并且您想要它的地址,使用addressof。

I'd say you should always use & because, as you say, if you don't, it defeats the purpose of the overload. Unless of course you do something meaningful with the overload, in which case you'd need addressof (outside the class, inside you can just use this), but you have to be very certain of what you're doing.

我认为你应该经常使用&因为,就像你说的,如果你不使用,它就会破坏超负荷的目的。当然,除非你在超负荷的情况下做了一些有意义的事情,在这种情况下你需要(在课堂之外,你可以使用这个),但是你必须非常确定你在做什么。

Here's more - if you want to overload operator& outside the class (you can), you have to use addressof to return the address, otherwise it results in infinite recursion:

如果你想重载operatorandoutside类(你可以),你必须使用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
}

I know this isn't safe.

我知道这不安全。

#3


6  

My opinion only:

我认为只有:

Unless you are part of the team designing the class and its interface, never. I've personally never seen a good reason to overload that operator. But if someone designs a class where it makes sense, and assuming the class is meant for public consumption(that is to say, the class is not for internal use only in a particular library), I will expect the class to work in normal code that naturally expects that & means "address of". If the class that overloads the operator isn't designed in such a sensible way, then I wouldn't use that class, period. Because either that class is broken, or it is not meant to be used outside the library which it is a part of.

除非您是设计类及其接口的团队的一员,否则永远不要这样做。我个人从未见过有什么好理由让那个操作者超负荷工作。但是如果有人设计一个类,它是有意义的,并假设类是对公共消费(也就是说,类不是仅供内部使用在一个特定的库),我将期待类工作在正常代码,自然希望&意味着“地址”。如果重载操作符的类不是以如此合理的方式设计的,那么我就不会使用那个类,句号。因为要么这个类被破坏了,要么它不打算在它所在的库之外使用。

#4


5  

Use it when you want to know the actual address of the object, and not the result of an address-of operator& overload.

当您希望知道对象的实际地址,而不是操作数和重载的地址的结果时,请使用它。

#5


4  

After all, they both return the "address of" the object, so when do I use which?

毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?

You have absolutely no guarantee that an overloaded operator& is the "address of" the object, chances are it isn't, or the class author probably wouldn't have bothered to overload it. They could have overloaded it to return a different type, or even to return void if they are ill-advisedly trying to prevent people taking its address.

您绝对不能保证重载操作符&是对象的“地址”,很可能它不是,或者类作者可能不会费心重载它。如果他们不明智地试图阻止人们使用它的地址,他们可能会让它返回另一种类型,甚至返回void。

If you want a pointer to an object which might have overloaded & (e.g. because its type is a template parameter so you don't know) then either use std::addressof or document that your template doesn't support types which don't return the object's real address as the right type.

如果您想要一个指向一个对象的指针,该对象可能已经重载了&(例如,因为它的类型是一个模板参数,所以您不知道),那么您可以使用std::addressof或文档,您的模板不支持不返回对象真实地址的类型作为正确的类型。