Topic: Overloading ->() operator in C++


Author: holiday@crchh82.NoSubdomain.NoDomain (Matthew Holiday)
Date: Thu, 07 May 1992 14:02:42 GMT
Raw View
In article <1992May6.210939.6695@sunb10.cs.uiuc.edu>, pjl@sunb4.cs.uiuc.edu (Paul Lucas) writes:
|> In <1992May06.191133.12128@bnr.ca> holiday@bnr.ca (Matthew Holiday) writes:
|>
|> >It's been pointed out that there's an operator "->", which is declared as ->().
|>
|> >What I meant was the operator "->()", which would have to be declared as ->()(), if
|> >a translator can swallow that without barfing.  The intent is so that constructs of
|> >the form
|> >          anObject->mbrFunction()
|> >are processed something like
|> >          operator ->() ( anObject, mbrFunction )
|> >where ->() translates into an RPC call or message send or something, using a smart
|> >pointer.
|>
|> >Can this be done without too much violence to C++ as it is?  Or will it require a
|> >translator with a special option which converts the -> and () combination into
|> >something special?  Any thoughts?
|>
|>  I'm sorry, but I still don't get what your after.  The current
|>  operator-> is a postfix unary operator that takes an object on
|>  its left-hand-side and is s'posed to return a pointer to an
|>  object to be dereferenced by the normal -> operator (or it can
|>  return a reference to another object for which -> is overloaded
|>  in whihc case the process repeats).
|>
|>  In your example, "anObject" is "this" and the other argument,
|>  which for the current -> can also be a data member so long as
|>  the permissions are correct.
|>
|>  Perhaps if you were to *briefly* describe what you are actually
|>  trying to do, it would help.
|> --
|>  - Paul J. Lucas    University of Illinois
|>    AT&T Bell Laboratories  at Urbana-Champaign
|>    Naperville, IL   pjl@cs.uiuc.edu

The point is that the thing to the right of -> could be a member function, where
"->()()" would overload the mechanism for calling a function through a pointer.

If the object is in another address space, overloading the -> and () operators
separately won't work, unless -> moves the object into the current address space.
This means an entirely new operator, which I suppose takes three things, the object,
the member function, and the function's arguments, and is responsible for de-
referencing the pointer, calling the function (in some manner), and returning the
result.  That way, one root class could override ->()() for a hierarchy of
distributed objects, in a very elegant manner.

---------------------------------------------------------------------------
Matt Holiday                                      #include <std/disclaimer>
holiday@bnr.ca
BNR Richardson





Author: holiday@crchh82.NoSubdomain.NoDomain (Matthew Holiday)
Date: Thu, 07 May 1992 14:08:51 GMT
Raw View
In article <1992May6.230913.26070@cbnewsl.cb.att.com>, kc@cbnewsl.cb.att.com (keith.coulson) writes:
|> In article <1992May06.141857.8930@bnr.ca>, holiday@bnr.ca writes:
|> >
|> > At some point (perhaps still), MCC had a C++ translator which allowed the
|> > operator ->() to be overloaded.  This operator could best be called ``call-
|> > member-fn-through-ptr-to-object.''  The point was to allow ease in devising
|> > smart pointers for distributed programming and making member function calls
|> > through them.
|> >
|> > Has there been any consideration of calling ->() an operator for ANSI C++,
|> > and allowing it to be overloaded?
|> >

|>
|> This sounds like the "wrappers" concept which I think is something like
|> the :before, :after methods in CLOS.  Didn't the MCC folks adopt a
|> different syntactic construct, however than overloading operator->() () to
|> implement this, as in :
|>
|> class foo
|> {
|>  ...
|>  virtual () foo (int (foo::*)(...)...);
|>  ...
|> };
|>
|> This may be out of date though, its from a 1988 USENIX C++
|> conference article.
|>
|> Anyway, what problems do you have with regular smart pointers for
|> handling distributed programming. I can think of a number of distributed
|> systems (Choices and SOS e.g.) that use C++ smart pointers to
|> provide uniform access to objects whether or not they are in the local
|> address space. Its a pain to generate the stubs for remote access by hand
|> and really need a stub generator, but isn't this still true, to some
|> extent, of the MCC technique?
|>
|> Keith Coulson
|> kco@usl.com

I am relying on my memory of a seminar I attended at CU Boulder a couple of years
ago.  If I remember correctly, they did in fact modify their C++ translator to be
able to override ->()(), then created a root class for distributed objects, and let
inheritance do its thing -- all the inherited objects could handle having their
member functions called through the smart pointer.  At any rate, whether or not
that's exactly what they did then, it sounds like a remarkably elegant solution to
the problem.  Leaving aside issues of synchronization or mutual exclusion, one could
take objects and make them distributed simply by making them inherit from the root
distributed object type.




Author: kc@cbnewsl.cb.att.com (keith.coulson)
Date: 7 May 92 15:45:55 GMT
Raw View
In article <1992May07.140242.19314@bnr.ca>, holiday@crchh82.NoSubdomain.NoDomain (Matthew Holiday) writes:

>
> If the object is in another address space, overloading the -> and () operators
> separately won't work, unless -> moves the object into the current address space.

You don't have to move the object into the local address space, you simply
make it point to a remote stub which marshalls the parameters and sends
the request. This could be done by deriving the local class and the
stub class from a common base and overloading -> in the smart pointer
to return a pointer to the base.

The constructor to such a smart pointer would probably take an object ID
which it would then use to determine if the object was local or remote
and then make its internal pointer point to either the local object
or otherwise create a stub and have it point to that.

In fact, if the remote object was const and  had a small amount of
state then you could cache it in the local address space by having the
the object copied and avoid RPCs on subsequent invocations.

The location of the remote object could change any number of times
during the liftime of the smart pointer by changing the smart pointers
internal pointer to either the local version or the stub and the smart
pointer would present the client with same interface throughout.

Keith Coulson
kco@usl.com




Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 7 May 92 19:30:09 GMT
Raw View

holiday@bnr.ca (Matthew Holiday @ Bell-Northern Research) writes

 > What I meant was the operator "->()", which would have to be declared as ->()(), if
 > a translator can swallow that without barfing.  The intent is so that constructs of
 > the form
 >           anObject->mbrFunction()
 > are processed something like
 >           operator ->() ( anObject, mbrFunction )
 > where ->() translates into an RPC call or message send or something, using a smart
 > pointer.
 >
 > Can this be done without too much violence to C++ as it is?  Or will it require a
 > translator with a special option which converts the -> and () combination into
 > something special?  Any thoughts?

See ARM pp333-334




Author: jimad@microsoft.com (Jim ADCOCK)
Date: 09 May 92 03:13:32 GMT
Raw View
In article <1992May06.191133.12128@bnr.ca> holiday@bnr.ca (Matthew Holiday) writes:
|It's been pointed out that there's an operator "->", which is declared as ->().
|
|What I meant was the operator "->()", which would have to be declared as ->()(), if
|a translator can swallow that without barfing.  The intent is so that constructs of
|the form
|          anObject->mbrFunction()
|are processed something like
|          operator ->() ( anObject, mbrFunction )
|where ->() translates into an RPC call or message send or something, using a smart
|pointer.

Consider that neither the object nor the member functin translate directly
accross process boundaries.  Thus both the object and the "member function"
must be some kind of "Smart Pointer" [or smart references]  The "member
function" then must be some kind of pointer-to-member-function.  The
syntax for representing calling a function through a pointer-to-object
and pointer-to-member-function in the normal case is as follows:

 (objptr ->* mfptr) (parms);

which when replaced with smart pointers becomes:

 (smrtobjptr ->* smrtmfptr) (parms);

But -- operator ->* is *already* overloadable as you desire!  Consider
the following partial cartoon sketch [ugly dispatch syntax -- but, that *is*
the syntax!]


#include <iostream.h>

typedef char* Method;

class Bind
{
 class Object* po;
 Method method;
public:
 Bind(Object*, Method);
 void operator()();
};

class Object
{
 char* name;
public:
 Object(char* nm) : name(nm) {}
 Bind operator ->* (Method method) { return Bind(this, method); }
 void print() { cout << name; }
};

Bind::Bind(Object* o, Method m) : po(o), method(m) {}

void Bind::operator()(/*could have parms bound here too*/)
{ cout << "Send "; po->print(); cout << " away with method " << method; }

Method method = "doSomething";

main()
{
 Object object("obj");

 (object ->* method) ();
};






Author: holiday@bnr.ca
Date: Wed, 06 May 1992 14:18:57 GMT
Raw View
At some point (perhaps still), MCC had a C++ translator which allowed the
operator ->() to be overloaded.  This operator could best be called ``call-
member-fn-through-ptr-to-object.''  The point was to allow ease in devising
smart pointers for distributed programming and making member function calls
through them.

Has there been any consideration of calling ->() an operator for ANSI C++,
and allowing it to be overloaded?

---------------------------------------------------------------------------
Matt Holiday                                      #include <std/disclaimer>
holiday@bnr.ca
BNR Richardson




Author: holiday@bnr.ca (Matthew Holiday)
Date: 6 May 92 19:11:33 GMT
Raw View
It's been pointed out that there's an operator "->", which is declared as ->().

What I meant was the operator "->()", which would have to be declared as ->()(), if
a translator can swallow that without barfing.  The intent is so that constructs of
the form
          anObject->mbrFunction()
are processed something like
          operator ->() ( anObject, mbrFunction )
where ->() translates into an RPC call or message send or something, using a smart
pointer.

Can this be done without too much violence to C++ as it is?  Or will it require a
translator with a special option which converts the -> and () combination into
something special?  Any thoughts?

---------------------------------------------------------------------------
Matt Holiday                                      #include <std/disclaimer>
holiday@bnr.ca
BNR Richardson




Author: pjl@sunb4.cs.uiuc.edu (Paul Lucas)
Date: 6 May 92 21:09:39 GMT
Raw View
In <1992May06.191133.12128@bnr.ca> holiday@bnr.ca (Matthew Holiday) writes:

>It's been pointed out that there's an operator "->", which is declared as ->().

>What I meant was the operator "->()", which would have to be declared as ->()(), if
>a translator can swallow that without barfing.  The intent is so that constructs of
>the form
>          anObject->mbrFunction()
>are processed something like
>          operator ->() ( anObject, mbrFunction )
>where ->() translates into an RPC call or message send or something, using a smart
>pointer.

>Can this be done without too much violence to C++ as it is?  Or will it require a
>translator with a special option which converts the -> and () combination into
>something special?  Any thoughts?

 I'm sorry, but I still don't get what your after.  The current
 operator-> is a postfix unary operator that takes an object on
 its left-hand-side and is s'posed to return a pointer to an
 object to be dereferenced by the normal -> operator (or it can
 return a reference to another object for which -> is overloaded
 in whihc case the process repeats).

 In your example, "anObject" is "this" and the other argument,
 which for the current -> can also be a data member so long as
 the permissions are correct.

 Perhaps if you were to *briefly* describe what you are actually
 trying to do, it would help.
--
 - Paul J. Lucas    University of Illinois
   AT&T Bell Laboratories  at Urbana-Champaign
   Naperville, IL   pjl@cs.uiuc.edu




Author: kc@cbnewsl.cb.att.com (keith.coulson)
Date: 6 May 92 23:09:13 GMT
Raw View
In article <1992May06.141857.8930@bnr.ca>, holiday@bnr.ca writes:
>
> At some point (perhaps still), MCC had a C++ translator which allowed the
> operator ->() to be overloaded.  This operator could best be called ``call-
> member-fn-through-ptr-to-object.''  The point was to allow ease in devising
> smart pointers for distributed programming and making member function calls
> through them.
>
> Has there been any consideration of calling ->() an operator for ANSI C++,
> and allowing it to be overloaded?
>
> ---------------------------------------------------------------------------
> Matt Holiday                                      #include <std/disclaimer>
> holiday@bnr.ca
> BNR Richardson


This sounds like the "wrappers" concept which I think is something like
the :before, :after methods in CLOS.  Didn't the MCC folks adopt a
different syntactic construct, however than overloading operator->() () to
implement this, as in :

class foo
{
 ...
 virtual () foo (int (foo::*)(...)...);
 ...
};

This may be out of date though, its from a 1988 USENIX C++
conference article.

Anyway, what problems do you have with regular smart pointers for
handling distributed programming. I can think of a number of distributed
systems (Choices and SOS e.g.) that use C++ smart pointers to
provide uniform access to objects whether or not they are in the local
address space. Its a pain to generate the stubs for remote access by hand
and really need a stub generator, but isn't this still true, to some
extent, of the MCC technique?

Keith Coulson
kco@usl.com