Topic: Is member operator& special?


Author: sdowney@sdowney.org (Steve Downey)
Date: Tue, 22 Feb 2005 18:56:50 GMT
Raw View
Scott Meyers wrote:
> If I declare a non-const member function and try to invoke it on a
> const object, the code won't compile.  Shouldn't this apply to operator&,
> too?  Consider:
>
>   class Widget {
>   public:
>     Widget(){}
>     void operator&(){}        // non-const
>   };
>
>   int main()
>   {
>     const Widget cw;
>     &cw;                      // should this compile?
>   }
>
> I claim this is invalid code, but a quick look at the standard doesn't
> provide ammo to back my claim.  All my compilers accept the code, which is
> weird, because I could swear I did this same test years ago and got the
> results I expected.
>
> Is the above code legit?  If so, why?
>
> Thanks,
>
> Scott
>

It appears to me that operator& is special, in that it is an operator
that applies directly to a class, but isn't of the compiler generated
functions. So by declaring operator&(), you aren't inhibiting
operator&() const. It's not that the operator& you wrote applies to a
const Widget, but that the built in & operator applies.

Changing the line to:
const Widget *w = &cw;  //should this compile?

still compiles on all the available compilers I have, indicating that
they think that built in & applies, since void operator&() certainly
would not.

Steve Downey
http://www.sdowney.org

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ron@sensor.com (Ron Natalie)
Date: Tue, 22 Feb 2005 21:18:15 GMT
Raw View
Steve Downey wrote:

>
> It appears to me that operator& is special, in that it is an operator
> that applies directly to a class, but isn't of the compiler generated
> functions.

Well, it's special in that it can be overloaded, but there is a default
action.   It's not unique however, the operators ||, &&, and , (comma)
also behave that way.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Usenet@aristeia.com (Scott Meyers)
Date: Wed, 16 Feb 2005 22:33:13 GMT
Raw View
If I declare a non-const member function and try to invoke it on a
const object, the code won't compile.  Shouldn't this apply to operator&,
too?  Consider:

  class Widget {
  public:
    Widget(){}
    void operator&(){}        // non-const
  };

  int main()
  {
    const Widget cw;
    &cw;                      // should this compile?
  }

I claim this is invalid code, but a quick look at the standard doesn't
provide ammo to back my claim.  All my compilers accept the code, which is
weird, because I could swear I did this same test years ago and got the
results I expected.

Is the above code legit?  If so, why?

Thanks,

Scott

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 17 Feb 2005 00:41:26 GMT
Raw View
Scott Meyers wrote:
> If I declare a non-const member function and try to invoke it on a
> const object, the code won't compile.  Shouldn't this apply to operator&,
> too?  Consider:
>
>   class Widget {
>   public:
>     Widget(){}
>     void operator&(){}        // non-const
>   };
>
>   int main()
>   {
>     const Widget cw;
>     &cw;                      // should this compile?
>   }
>
> I claim this is invalid code, but a quick look at the standard doesn't
> provide ammo to back my claim.  All my compilers accept the code, which is
> weird, because I could swear I did this same test years ago and got the
> results I expected.
>
> Is the above code legit?  If so, why?
>

Yes, the code is legal. The member function Widget::operator&() above is
not a "viable function" when operator & is applied to a const object, so
13.3.1.2/9 kicks in:

"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."

In other words, providing a non-const overload for operator & does not
hide the built-in operator & for const objects. If you want to avoid
applying operator & to const objects, you can do like this:

class Widget {
public:
   Widget(){}
   void operator&(){}        // non-const

private:
   void operator&() const;   // declared but not defined
};

BTW, why would you want operator& to return void?

HTH,

Alberto

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Jerry Coffin" <jcoffin@taeus.com>
Date: Wed, 16 Feb 2005 18:41:25 CST
Raw View
Scott Meyers wrote:
> If I declare a non-const member function and try to invoke it on a
> const object, the code won't compile.  Shouldn't this apply to
> operator&, too?  Consider:
>
>   class Widget {
>   public:
>     Widget(){}
>     void operator&(){}        // non-const
>   };
>
>   int main()
>   {
>     const Widget cw;
>     &cw;                      // should this compile?
>   }
>
> I claim this is invalid code, but a quick look at the standard
> doesn't provide ammo to back my claim.  All my compilers accept
> the code, which is weird, because I could swear I did this same
> test years ago and got the results I expected.
>
> Is the above code legit?  If so, why?

I believe it is.

You've provided a member overload, and as far as I can see from
13.3.1.2, there are no other candidates for overload resolution (you've
provided no non-member overload, and for unary operator&, "the built-in
candidates set is empty" (third major "-" sub-clause of 13.3.1.2/3).
That candidate is considered in light of 13.3.2 to see if it's viable.
Your overload would require converting 'this' from 'Widget const *' to
"Widget *', which can't be done implicitly, so it's not viable.

Lacking a viable overload candidate, $13.1.2/9 says the built-in
operator will be used. As you'll note, this provision is unique to
three operators (comma, address-of and pointer-to-member), so if you
previously tested with any but these three, the different result would
be expected.

If you want to prevent compilation, provide a private, const-qualified
overload. Both your overloads will be candidates, but the one that's
not const-qualified will be eliminated as before. Since this is the
only viable function, it's also the best viable function ($13.3.3).
Since it's inaccessible, compilation fails.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Usenet@aristeia.com (Scott Meyers)
Date: Thu, 17 Feb 2005 18:23:23 GMT
Raw View
On Thu, 17 Feb 2005 00:41:26 GMT, Alberto Barbati wrote:
> BTW, why would you want operator& to return void?

I was just looking for "the simplest thing that could possibly fail," i.e.,
not compile.  My original motivation for the question was that somebody
asked me if operator& was one of the compiler-generated member functions.
It's not listed as a special function in clause 12, so I was looking for a
way to demonstrate that it's not compiler generated as

  class T {
  public:
    T*       operator&()       { return this; }
    const T* operator&() const { return this; }
  };

In the past, declaring one and not the other has worked as per my example.
Now I guess I'll have to demonstrate it by trying to take its address.
That seems to work as expected, i.e., taking the address of an undeclared
member operator& fails.

Scott

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]