From -8871271480843932476
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,c0e61b6a667823c0
X-Google-Attributes: gidf78e5,public
From: sbnaran@localhost.localdomain (Siemel Naran)
Subject: Re: no const operator[] in STL map?
Date: 1999/01/25
Message-ID: <slrn7anvsm.8jt.sbnaran@localhost.localdomain>#1/1
X-Deja-AN: 436584031
Approved: Fergus Henderson <fjh@cs.mu.oz.au>
References: <916993358.766341@aloomba.aaii.oz.au> <slrn7ai4q5.9dj.sbnaran@fermi.ceg.uiuc.edu> <36ABD140.DAC0F0AA@mindspring.com>
X-Original-Date: 25 Jan 1999 05:23:26 GMT
X-Complaints-To: news@news.unimelb.edu.au
X-Trace: izvestia.its.unimelb.edu.au 917247281 32675 128.250.29.17 (25 Jan 1999 06:54:41 GMT)
Organization: University of Illinois at Urbana-Champaign
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUANqwVDeEDnX0m9pzZAQG/pgF/fhvxk4XwwmMJHUmLBYVyZohxlcO2BrGg 7U+DAw3yXpvRp/4VigzG+wsxgtCt9Joj =/PCq
Reply-To: sbnaran@uiuc.edu
NNTP-Posting-Date: 25 Jan 1999 06:54:41 GMT
Newsgroups: comp.std.c++

On 25 Jan 99 02:34:00 GMT, Bruce Visscher <bvisscher@mindspring.com> wrote:
>Siemel Naran wrote:

>> No, the standard does not have such an operator.
>> I wish it did.
>
>Me too.


>> But there is a logical alternative if const operator[] can't
>> find the object with key_type 'key' in the map.  Just throw an
>> exception.
>
>I agree that it would have been nice had the standard provided a const
>operator[].  However, I don't agree that it should throw.  To me there is an
>obvious alternative: return by value rather than by reference and return
>mapped_type() if the key is not found.

This would involve lots of copying if mapped_type were a large
object.  Besides, the user may want to know if the lookup of
the object failed as they may write code like this:

   try
   {
      int i;
      cin >> i;
      map[i]=9;
   }
   catch (typeof(map)::non_existent) { }
   
   
>One useful application for map suggested in [Musser & Sauni] is that of a
>sparse array.  With a const overload implemented like this you would get
>consistent behavior (m[x] returns mapped_type() if x is not found whether or
>not m is const).  In fact, the const overload would be the one to use if
>wherever possible for a sparse vector.  You wouldn't want to allocate
>10000000 elements if you did:

Once one has an operator[] that throws an exception if the object does
not exist, one can write an adaptor that returns a value, and a default
value if the object does not exist.  But if one has an operator[] that
returns a value, then one can't engineer this to turn it into a
function that throws if the object didn't exist.


>There is precedence for my suggestion too (typing the following in from my
>pdf copy, I hope I don't make any mistakes):
>
>26.3.2 Template class valarray
>[...]
>  template<class T>
>  class valarray {
>[...]
>        // 26.3.2.3 element access:
>        T            operator[](size_t) const;
>        T&         operator[](size_t);
>[...]
>
>It's not that unusual in my experience to see non-const overload of
>operator[] return by reference while the const overload returns by value.

The reason why valarray<T> can have its constant operator[] return
by value is that there is something to return.

I have no idea why valarray<T> returns by value.  It should just
return by const reference.  As operator[] is inline, the lvalue
returned (ie, const T&) should be converted at compile time to an
rvalue (ie, T).


>This seems to bother some, though, so you could instead return by reference
>to const and statically allocate a default constructed mapped_type when
>needed instead (i.e., the first time map::operator[] const was invoked for a
>non-existant key).

The use of static objects to represent null objects (so that you
can return a null reference) may makes things harder for
maintainance.  This is because the usual semantics of operator[]
is to return a reference to an existing object.  The user need
not bother to check whether the reference is valid; instead the
user can assume that the reference is valid.  When returning
by pointer, it makes sense for the user to check whether the
returned pointer is valid -- ie, they test the pointer against
'null' or '0'.

But returning a reference to a so-called null object means that
users may have to check their references against null.  This
appears to be a little non-intuitive.  Moreover, how do users
check their objects against null object?  Do they compare the
returned reference to the null object, ie. use operator==(T,T)?
Or do they compare the address of the returned reference against
the address of the null object, ie. use operator==(T*,T*)?  If
the latter, then is the null object const or not?

-- 
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]



