What legitimate reasons exist to overload the unary operator&?
Asked Answered
L

6

71

Okay, I've been inspired to do some head punching. Seems like overloading operator& leads to not a small amount of pain.

What legitimate cases exist for overloading it?

(Can't say I've ever done that....)

Laurinelaurita answered 27/6, 2011 at 16:32 Comment(0)
E
53

I seem to remember something like a smart pointer class which overrode operator& because it wanted to return the address of the contained pointer rather than the address of the smart pointer object. Can't remember where I saw it or whether it seemed like a good idea at the time.

Aha, remembered: Microsoft's CComPtr.

Edit: To generalize, it might make sense under the following conditions:

  • You have an object which is masquerading as some other object.
  • This object can obtain a pointer to the thing it's masquerading as.

Returning anything other than a legitimate pointer would violate the principle of least astonishment.

Eusporangiate answered 27/6, 2011 at 16:43 Comment(4)
@Billy, it's been a very long time since I used this and I just don't remember the pros/cons. Since passing the address of an interface pointer is a common operation in COM programming it seems defensible.Eusporangiate
"address of the contained pointer" you mean the contained pointer, don't you?Innerdirected
@Innerdirected I don't think so. The contained pointer has type T *. The pointer returned by operator& has type T **, and points to the contained pointer.Fevre
The operator& overload in CComPtr is a dangerous hack. It works only if the smart pointer isn't already initialized. Otherwise, the object it already holds won't get its reference count decremented, and leaks abound. In debug builds, it actually asserts that the pointer is already null because this kind of error was way too common.Hell
F
12

It is useful when representing the & operation in lambda placeholder notation, e.g. &_1[_2].

Fieldpiece answered 21/3, 2015 at 9:19 Comment(0)
W
10

Overloading unary & makes your object behave like a reference (in that respect).

I'm pretty sure that it's a fool's errand to attempt to provide alternatives to built-in references, in particular since references aren't objects at all in C++, and they don't have their own addresses. Instances of your user-defined type inevitably are objects, and do have addresses, even if you disable the normal way of obtaining that address. So it is never a perfect imitation.

But, people are very keen on user-defined alternatives to pointers, so I can sort of see how someone might want to attempt it. I'm not sure they'll avoid creating a type that (mis)behaves in ways that will make its users wish they hadn't bothered.

Warms answered 27/6, 2011 at 23:18 Comment(5)
But isocpp.org/wiki/faq/references#overview-refs says that: " Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object. It is not a pointer to the object, nor a copy of the object. It is the object. "Oblast
@PravasiMeet: it's unfortunate they put it that way, since the standard explicitly says that a reference is not an object. It's like the name of a variable: the variable is an object but its name isn't. The referand of a reference is an object but the reference itself is not.Warms
can you please tell the standard citation that explicitly says that a reference is not an object.Oblast
@PravasiMeet: hmm, I thought there was a straight statement but at the moment I can't find it so perhaps it's not explicit after all. However, [intro.object] says "An object is a region of storage", and [dcl.ref] says in a note "A reference can be thought of as a name of an object" and normatively "It is unspecified whether or not a reference requires storage".Warms
Also observe in the FAQ, first it says "What is a reference? An alias (an alternate name) for an object". So if they're saying that a reference is a name, and a reference is the object, then as long as they would say that a name is the object then they're consistent. However, so far as the jargon of the C++ standard is concerned, the name of an object is not an object either. It represents the object in expressions, that's not the same as being identical with the object, but in English "is" can mean either thing.Warms
Q
8

I've done this to good effect in the context of a DSL that generates LLVM code. An example will illustrate. Say x and y are values (i.e., objects of type value). Then the expression x+y emits an ADD instruction into some code stream. Quite sensibly, the expression &x emits an instruction to take the address of x.

Quaff answered 15/9, 2014 at 20:55 Comment(0)
C
8

Four years later, another answer.

Another use I have seen is when you are piggybacking off of the C++ language, but defining your own semantics. Prime example: Boost.Spirit.

Boost.Spirit, in particular Qi for parsing, overloads operators on parsers to provide an EBNF-like syntax for specifying arbitrary parser objects. In particular, the unary & operator is overloaded to provide the And-Predicate Parser.

And-Predicate Parser (&a)

Description

Syntactic predicates assert a certain conditional syntax to be satisfied before evaluating another production. Similar to semantic predicates, eps, syntactic predicates do not consume any input. The and-predicate, &a, is a positive syntactic predicate that returns a zero length match only if its predicate matches.

Example usage:

Basic look-ahead example: make sure that the last character is a semicolon, but don't consume it, just peek at the next character:

test_phrase_parser("Hello ;", lit("Hello") >> &lit(';'), false);

So in short, the unary & here has no relation to pointers at all; it has domain-specific semantics which apply to Qi parser objects.

Canaigre answered 21/9, 2015 at 5:43 Comment(1)
In short, it's the same answer with another example of an expression templatePiwowar
G
0

Once I used to override operator & (without altering its behavior) as private to the class, in order to protect against occasional creation of smart pointer to the object created in the stack. Still not sure if it was really good idea...

Goliath answered 4/3, 2012 at 5:46 Comment(1)
That's a bad idea because you didn't achieve your goal. See: #6495091Laurinelaurita

© 2022 - 2024 — McMap. All rights reserved.