Topic: Operator -> cannot return non-class types?


Author: dlarsson@aut.abb.se (Daniel Larsson)
Date: 11 Nov 92 09:23:16 GMT
Raw View
Yesterday, I tried HP's new C++ compiler (3.0) and templates for the first
time. To my surprise, I noticed that operator -> can only return the following
three types:
   - a pointer to a class,
   - a class, or
   - a reference to a class.

This means I cannot do simple things like:

  template< class T >
  class OffsetPtr
    {
    public:
      OffsetPtr();
      OffsetPtr( T* );
      ...
      T* operator ->();
      ...
    };

  OffsetPtr<char> ptrToString;


What is the rationale behind this restriction? I couldn't find anything in
C++PL 2nd ed. that mentions this restriction, although I didn't look too hard.

-- Daniel


--
---------------------------------------------------------------------------
Daniel Larsson          Email:    dlarsson@aut.abb.se
ABB Automation AB Telefax:   +46 21 34 25 25
V{ster}s, Sweden Telephone: +46 21 34 30 29




Author: mccauleyba@vax1.bham.ac.uk (Brian McCauley)
Date: Wed, 11 Nov 1992 18:43:41 GMT
Raw View
In article <1992Nov11.092316.306@aut.abb.se>, dlarsson@aut.abb.se (Daniel Larsson) writes:
> To my surprise, I noticed that operator -> can only return the following
> three types:
>    - a pointer to a class,
>    - a class, or
>    - a reference to a class.
>
> This means I cannot do simple things like:
>
>   template< class T >
>   class OffsetPtr
>     {
>     public:
>       OffsetPtr();
>       OffsetPtr( T* );
>       ...
>       T* operator ->();
>       ...
>     };
>
>   OffsetPtr<char> ptrToString;
>
> What is the rationale behind this restriction? I couldn't find anything in
> C++PL 2nd ed. that mentions this restriction, although I didn't look too hard.

a->b
  ...where a is of a class type is interpreted as...
(a.operator->())->b
  ...which in turn may expand to...
((a.operator->()).operator->())->b
  ...and so on.

but in all cases the thing on the rhs of the -> is a class member. Since
types other that structs and classes do not have members it would be
useless for operator->() to return anything other than a pointer to a class or
a class for which operator->() is also defined.

Now what you could do is define operator T* (). Unfortuneately if you write
`a->b' where a is of a class without an operator->() the compiler does not
try compiling it as `(*a).b' so you'll have to write this out in full each
time. Likewise you can't write `a[5]' but you can write `*(a+5)'.

This has annoyed me in the past and I feel that the language definition
should employ user defined type conversions to resolve the lh operand of
the -> ->* and [] operators.
--
    \\   ( )  NO BULLSHIT! from BAM (Brian McCauley)
 .  _\\__[oo
.__/  \\ /\@  E-mail: B.A.McCauley@bham.ac.uk
.  l___\\        Fax: +44 21 625 2175
 # ll  l\\     Snail: 197 Harborne Lane, Birmingham, B29 6SS, UK
###LL  LL\\     ICBM: 52.5N 1.9W




Author: kanze@us-es.sel.de (James Kanze)
Date: 13 Nov 92 19:16:17
Raw View
In article <1992Nov11.092316.306@aut.abb.se>, dlarsson@aut.abb.se
(Daniel Larsson) writes:

|> > To my surprise, I noticed that operator -> can only return the following
|> > three types:
|> >    - a pointer to a class,
|> >    - a class, or
|> >    - a reference to a class.
|> >
|> > This means I cannot do simple things like:
|> >
|> >   template< class T >
|> >   class OffsetPtr
|> >     {
|> >     public:
|> >       OffsetPtr();
|> >       OffsetPtr( T* );
|> >       ...
|> >       T* operator ->();
|> >       ...
|> >     };
|> >
|> >   OffsetPtr<char> ptrToString;
|> >
|> > What is the rationale behind this restriction? I couldn't find anything in
|> > C++PL 2nd ed. that mentions this restriction, although I didn't look too hard.

|> a->b
|>   ...where a is of a class type is interpreted as...
|> (a.operator->())->b
|>   ...which in turn may expand to...
|> ((a.operator->()).operator->())->b
|>   ...and so on.

|> but in all cases the thing on the rhs of the -> is a class member.
|> Since types other that structs and classes do not have members it
|> would be useless for operator->() to return anything other than a
|> pointer to a class or a class for which operator->() is also defined.

|> Now what you could do is define operator T* (). Unfortuneately if you
|> write `a->b' where a is of a class without an operator->() the
|> compiler does not try compiling it as `(*a).b' so you'll have to write
|> this out in full each time. Likewise you can't write `a[5]' but you
|> can write `*(a+5)'.

|> This has annoyed me in the past and I feel that the language
|> definition should employ user defined type conversions to resolve the
|> lh operand of the -> ->* and [] operators.

IMHO, this should only be a problem in templates.

Basically, I don't offhand see anything in the language definition
that would restrict an operator->() (the function) from returning
whatever it wishes.  On the other hand, there is no way to use this
operator *unless* it returns a pointer to a class.  This is no doubt
why your compiler introduced the restriction.

Normally, of course, you would never want to write a function that
could not be called.  However, in the case of templates, it is
possible that you might, since it could be called for the
instantiations using a class type, and any attempt to use it for the
instantiations using a non-class type would cause a compiler error at
the point of use.

(Actually, you can call the function, even for a non-class type
result, explicitly: "c = operator->( p ) ;", for example.  However, I
don't think that this is really the idea behind operator overloading.)
--
James Kanze   GABI Software, Sarl.
email: kanze@us-es.sel.de 8 rue du Faisan
    67000 Strasbourg
    France




Author: steve@taumet.com (Steve Clamage)
Date: Sat, 14 Nov 1992 22:03:18 GMT
Raw View
kanze@us-es.sel.de (James Kanze) writes:

>Basically, I don't offhand see anything in the language definition
>that would restrict an operator->() (the function) from returning
>whatever it wishes.  On the other hand, there is no way to use this
>operator *unless* it returns a pointer to a class.

ARM 13.4.6:

"... operator->() must return either a pointer to a class or an object
of or a reference to a class for which operator->() is defined."

That seems pretty clear.  The compiler was correct to reject a
declaration with any other sort of return type.
--

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16