[comp.lang.c++] Overloading operator {

pcg@cs.aber.ac.uk (Piercarlo Grandi) (10/08/90)

A while ago Ron Guilmette objected to overloading everything that moves
or not and looks like punctuation in C++, and he mused that sooner or
later somebody would want to overload operator {.

Well, I have found a sensible use for overloading operator { :->.

A bit of introduction: I am deeply unhappy with the existing
constructor/destructor facility in C++, on several grounds:

1) It looks to me conceptually wrong; it is just a special casing of
scope begin/end functions. Indeed, the way in C++ to define scope
begin/end functions for blocks and procedures is precisely to define a
dummy class with a constructor and destructor in those roles.

2) It is opaque; a tenet of C design was that all operations that looked
simple in the program text were simple in the generated code. In Classic
C the most expensive operation arguably was procedure call, and it was
obvious that its cost was proportional to its size (but for structure
passing, which indeed, with structure assignment, I regarded as a
regrettable addition to the language, just like enums).

3) The syntax chosen for constructors and destructors on C++ is
unfortunate; it is highly unsymmetric and unobvious, creates confusion
with casts (intended, presumably), and is ugly when one wants to
separate construction and destruction from memory allocation and
deallocation.

The first two points are fundamental to C++ (regrettably, just consider
virtual functions and base classes for a glaring example of the latter),
but the third is not. I think that a nice way to define constructors and
destructors would be to define operator { (scope begin) as the
constructor identifier, and operator } (scope end) as the destructor
identifier, and both must return void, and have as first parameter a
reference to an object of the class to whcih they apply.

Example:

	struct complex { float re,im; }

	static inline void operator {
	(
	    auto complex &c,
    	    auto float re = 0.0,
	    auto float im = 0.0
    	)
	{
	    c.re = re; c.im = im;
    	}

I would use the Classic C initialization syntax here, instead of the
many (and ambiguous) new ones for C++; something like:

	complex c1 = { 1.0, -1.0 }; // invokes operator {
	

Note that here I use 'scope' in the Algol 68 sense, i.e. the dynamic
one, that of an object's lifetime, not that of its visibility; in C/C++
an object may have program scope (static,extern), automatic scope (auto,
register) or manual scope (new).

Note that using operator { and operator } for constructors and
destructors has a number of nice consequences, such as that both become
easy to call explicitly, they do not need to be member functions (and
thus fit in easily with my ideas to abolish them entirely).

Why choose to overload the { and } punctuation characters? Well, because
in some sense they can be considered to be scope begin and end operators
for blocks (initialize stack frame, deinitialize it). The allocation and
reclamation functions for automatic scope are hidden, and usually
inlined in the generated code, unless one uses the GNU alloca() of
course, which is kind of a direct equivalent of Algol 68's LOC.

So, it makes some sense to "overload" operator { and operator }, at
least as much as overloading CLASSNAME and ~CLASSNAME, and, IMNHO, quite
a bit more.

(I will spare you a proposal to overload operator ; for a while at least
:->).
--
Piercarlo "Peter" Grandi           | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk