Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!ukc!edcastle!dcl-cs!aber-cs!athene!pcg From: pcg@cs.aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.lang.c++ Subject: Overloading operator { (really! :->) Message-ID: Date: 8 Oct 90 09:23:00 GMT Sender: pcg@aber-cs.UUCP Organization: Coleg Prifysgol Cymru Lines: 83 Nntp-Posting-Host: odin 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