18

Let's consider a class with overloaded unary operator & (Address-of). Let it be class A

template <class C>
class A
{
public:
    C * operator &()
    {
        return &data;
    }
    //...
private:
    C data;
}

Now I want to pass to some function a pointer of type A to fill its data. Let us call it f

void f(A * auto_containter)
{
    //...
}

But it is clear why the code bellow wouldn't work (even wouldn't compile). It is because the overloaded operator is called.

A a;
f(&a);

The question is following:

Is there any syntax to pass address of a to f? If no, then for me it is very strange why it is allowed to overload unary operator &, because it makes code more buggy and difficult to understand. Or there are some other reasons?

Mihran Hovsepyan
  • 10,810
  • 14
  • 61
  • 111
  • 1
    Abusing operator overloading does make the code harder to decode (and thus understand). Like all tools that are provided don't abuse them. – Martin York Jun 20 '11 at 13:47
  • You asked for *syntax* so this isn't an answer, but you could write `A * A::addressof() { return this; }` – Ben Jackson Jun 20 '11 at 18:01
  • Related: [Why is overloading operator&() prohibited for classes stored in STL containers?](http://stackoverflow.com/questions/2719832/why-is-overloading-operator-prohibited-for-classes-stored-in-stl-containers) – Balanivash Jun 20 '11 at 11:20

6 Answers6

18

Is there any syntax to pass address of a to f?

Yes, there's ugly syntax:

f( reinterpret_cast<A*>( &reinterpret_cast<char&>(a) ) );

boost::addressof is a nice and generic wrapper around it.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
14

Use std::addressof function(or boost::addressof pre C++11). In any case, overloading unary & is highly dubious. Why do it instead of having a named function that returns the address of your data?

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 3
    I agree that it's dubious, possibly even a mistake in the standard to permit it since the address of an object is a more fundamental concept than the operator used to obtain it, which is why every type works with `operator&` by default, unlike say `operator+`. But the classic answer to the "why do it" is to say, "I don't want to use a named function because I want to write generic code that takes addresses, and works with `int`, but when this class is used in that generic code I want it to use this other address". So explain why that's a mistake and we're done ;-) – Steve Jessop Jun 20 '11 at 11:24
  • 4
    For instance, you could change the generic code to use a type traits template to get the address, rather than unary &. – Steve Jessop Jun 20 '11 at 11:27
  • 7
    This functionality was included in C++11 as `std::addressof()`. – Hugues Apr 19 '14 at 18:01
4

Is there any syntax to pass address of a to f?

Others have already pointed out boost::addressof. The mechanism it relies on is a standard-guaranteed use of the built-in address operator for a reinterpret_cast to reference type. The Boost function just wraps the rather verbose and awkward combination of casts.

If no, then for me it is very strange why it is allowed to overload unary operator &, because if will make code more buggy and difficult to understand. Or there are some other reasons?

In some cases it can be more convenient. For example, a smart pointer class might offer a custom address operator in order to support writing &p as actual argument to a T** formal argument. However, I think nowadays it’s generally recognized that it isn’t all that good an idea.

Cheers & hth.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

Why would you ever want to overload the unary operator&?

Aside from that, there is boost::addressof.

Xeo
  • 129,499
  • 52
  • 291
  • 397
  • I my opinion: It would have been very useful to have `std::reference_wrapper` http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper to overload `operator&` to `return _ptr;`. Unfortunately it was not implemented and the resulting user code is less generic that what it could be. – alfC Oct 22 '15 at 07:20
1

This is why boost::addressof was invented.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
1

Your scenario never really comes up, because anyone who is writing that function will take a reference, not a pointer. Plus, you forgot to instantiate A with an example type for C.

Puppy
  • 144,682
  • 38
  • 256
  • 465