Topic: operator&


Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/06/28
Raw View

If I define a class with no operator& declared, I can still take the
address of both const and non-const instances of that class:

  class Widget {
  ...               // no declarations for operator&
  };

  Widget w;
  Widget *pw = &w;          // take address of non-const Widget

  const Widget cw;
  const Widget *pcw = &cw;  // take address of const Widget

This suggests that, in accord with 5.3.1/2, the compiler is applying the
built-in operator& to each object.

Of course, I can declare operator& functions if I choose, and, in accord
with 13.6/1, mine will be used instead of the compiler-generated ones.
Thus:

  class Widget {
  public:
    const Widget* operator&() const;
    Widget* operator&();
  };

  Widget w;
  Widget *pw = &w;            // calls non-const Widget::operator&

  const Widget cw;
  const Widget *pcw = &cw;    // calls const Widget::operator&

But what if I declare just ONE of the above operators?  For example:

  class Widget {
  public:
    Widget* operator&();
  };

  Widget w;
  Widget *pw = &w;            // as above, calls non-const Widget::operator&

  const Widget cw;
  const Widget *pcw = &cw;    // what happens here?

By declaring only the non-const operator&, do I prevent clients from taking
the address of const objects?  13.6/1 seems to suggest that I do:

  If there is a user-written candidate with the same name and parameter
  types as a built-in candidate operator function, the built-in candidate
  function is hidden and is not included in the set of candidate functions.

But if memory serves me (and forgive me for not plowing through the final
overloading rules to check this), when considering member functions during
overloading resolution, each member function is considered to have an extra
parameter corresponding to the "this" pointer.  For the non-const operator&,
this extra parameter is of type T*.  For the const operator&, it's of type
const T*.  That suggests to me that the user-declared non-const operator&
should not hide the use of the built-in operator& for const objects,
because the parameter types don't match.

In summary, if a class declares only a non-const unary operator&, does that
prevent class clients from taking the address of const objects?

As a bonus question, if the answer to this question is "Yes", would
declaration of a binary operator& prevent taking the address of _any_
object of the class?  Note the following (which is 13.5.1/2):

  The unary and binary forms of the same operator are considered to have
  the same name.  [Note: Consequently, a unary operator can hide a binary
  operator from an enclosing scope, and vice versa.]

Thanks,

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Dag Henriksson <dag.henriksson@quidsoft.se>
Date: 1999/06/28
Raw View


Scott Meyers wrote:

>   class Widget {
>   public:
>     Widget* operator&();
>   };
>
>   Widget w;
>   Widget *pw = &w;            // as above, calls non-const Widget::operator&
>
>   const Widget cw;
>   const Widget *pcw = &cw;    // what happens here?
>
> By declaring only the non-const operator&, do I prevent clients from taking
> the address of const objects?  13.6/1 seems to suggest that I do:

I read it like this:

13.3.1.2 / 3
Qualified lookup will be done of Widget::operator&

The set of member candidates from qualified lookup is only
operator&(Widget &)  (Widget & is an implicit object parameter)

The set of non-member candidates is empty

The set of built-in candidates is empty for unary operator &
according to 13.3.1.2 / 3

Now we should choose a set of viable function from the set of
candidate functions:

13.3.2 / 3
"for F to be a viable function, there shall exist for each argument an
implicit conversion sequence"

const Widget cw" can't refer to "Widget&"
so there are no viable functions.

113.3.1.2 /9
"If the operator is the operator ,, the unary operator &, or the operator ->,
and there
are no viable functions, then the operator is assumed to be the built-in
operator and
interpreted according to clause 5"

To answer your question,
const Widget *pcw = &cw;    // what happens here?

The built-in operator & will be called.

-- Dag Henriksson



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]