Topic: STL More Complexity than It's Worth?


Author: ajenkins@javanet.com
Date: 1998/10/06
Raw View
In article <6v2v58$ka5$1@nnrp1.dejanews.com>,
  jkanze@otelo.ibmmail.com wrote:
> I think that there is a subtle efficiency issue, which may account for
> why the function is missing.  Often, if the key is contained, you then
> want to access it.  Writing:
>
>     if ( aMap.contains( key ) )
>         //  Do something with aMap[ key ]
>
> involves two look-ups.  My own associative arrays handled this by caching
> the last value looked up, but there was still some cost to determine
> whether the cache value was really the one we wanted (and you payed this
> cost on every access).  The STL idiome for this is:
>
>     map< X , Y >::iterator
>                     item = aMap.find( key ) ;
>     if ( item != aMap.end() )
>         //  Do somethine with *item
>
> Only one look up.

It may be true that for std::map you do usually follow a successful key lookup
with an access to the associated value.  If you know that's what you're going
to do then it makes sense to use find, and avoid doing the lookup twice.  But
for std::set this is not the case.  Here especially it would make sense for
std::set to have a contains member.

Adam
--
Adam P. Jenkins
ajenkins@javanet.com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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              ]






Author: Matt Austern <austern@sgi.com>
Date: 1998/10/06
Raw View
ajenkins@javanet.com writes:

> having a standard implementation of them.  By the same logic,
> checking for membership in a set is a very fundamental operation on
> a set (try to find me any other set or hash table implementation
> from another language that doesn't have a membership function) so it
> seems to be an obvious oversight that it was left out of STLs set
> and map classes.

It wasn't left out; it's just not spelled the way you expect.

If you want to test whether a key k is present in an STL
associative container A, you write:
  if (A.count(k) != 0) {
    /* do something */
  }

The only difference between "count" and "contains" is that the return
value is an integer, not a bool.

For a Unique Associative Container (e.g. set or map), "count" always
returns 0 or 1, so it's precisely the membership predicate you're
looking for.

For a Multiple Associative Container, where there might be several
different elements with a key k, the notion of membership is
generalized: *how many* times is something a member?
---
[ 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              ]






Author: mborgerd@my-dejanews.com
Date: 1998/10/07
Raw View
In article <6ubc90$tc8$1@nnrp1.dejanews.com>,
  jkanze@otelo.ibmmail.com wrote:
>  For some reason,
>
>     assert( myMap.find( key ) == myMap.end() ) ;
>
> just doesn't seem as clear as
>
>     assert( ! myMap.contains( key ) ) ;
>

Efficiency is one of the main reasons these types of operations don't exist.
Consider the function:

bool Foo::Update(Key key,Data data)
{
  if ( ! m_map.contains(key))// fn. doesn't exist, but it would be O(log(n))
    return false;
  m_map[key] = data;// efficiency is O(log(n))
  return true;
}

The above function would be made nearly twice as efficient for large n by
changing it to:

bool Foo::Update(Key key,Data data)
{
  std::map<Key,Data>::iterator it;
  it = m_map.find(key);// this is O(log(n))

  if (it == m_map.end())// this is O(1)
    return false;
  (*it).second = data;// this is also O(1)
  return true;
}

Mark Borgerding
Sr. Software Developer
Sterling Commerce, Inc.
email-- mborgerding (AT) acm.org

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/10/02
Raw View
In article <slrn7150j7.7sm.sbnaran@fermi.ceg.uiuc.edu>,
  sbnaran@KILL.uiuc.edu wrote:
> On 30 Sep 1998 16:18:59 GMT, Adam P. Jenkins <ajenkins@javanet.com>
wrote:
>
> >I agree, I believe it is an oversight for a map class not to have a
> >contains(key) method; I find the
> >    aMap.find(key) == aMap.end()
> >idiom to be tedious to write over and over, and less intuitive than
> >    aMap.contains(key)
>
> This func is not part of the minimal interface.  It can be implemented
> maximally efficiently in terms of the other funcs.

I think that there is a subtle efficiency issue, which may account for
why the function is missing.  Often, if the key is contained, you then
want to access it.  Writing:

    if ( aMap.contains( key ) )
        //  Do something with aMap[ key ]

involves two look-ups.  My own associative arrays handled this by caching
the last value looked up, but there was still some cost to determine
whether the cache value was really the one we wanted (and you payed this
cost on every access).  The STL idiome for this is:

    map< X , Y >::iterator
                    item = aMap.find( key ) ;
    if ( item != aMap.end() )
        //  Do somethine with *item

Only one look up.

Since the user can always arrange to get an iterator from a single
lookup, and use that, there is no need for the cached item, and the total
performance is better.

Is it worth it?  My own containers were always optimized for convenience,
and not performance, but in this case, the difference in convenience is
very small, probably largely a matter of habit.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: ajenkins@javanet.com
Date: 1998/10/03
Raw View
In article <slrn7150j7.7sm.sbnaran@fermi.ceg.uiuc.edu>,
  sbnaran@KILL.uiuc.edu wrote:
> >    aMap.contains(key)
>
> This func is not part of the minimal interface.  It can be implemented
> maximally efficiently in terms of the other funcs.

Neither is list::empty() part of a minimal interface, since it can be
easily
implemented by
   alist.begin() == alist.end()
yet it's part of the standard container requirements.  The same can be
said of
front() (can be *cont.begin()), and back() (*cont.end()), and clear()
(cont.erase(cont.begin(), cont.end()).  Yet they're all included in the
standard container requirements because they are used so often that it's
worth
having a standard implementation of them.  By the same logic, checking
for
membership in a set is a very fundamental operation on a set (try to
find me
any other set or hash table implementation from another language that
doesn't
have a membership function) so it seems to be an obvious oversight that
it was
left out of STLs set and map classes.

In addition, aMap.contains(key) could be more efficient than
aMap.find(key)
!= aMap.end() because the second method has to actually create two
iterators
and then compare them, whereas the contains() function could return
true/false as soon as it finds the key in the map, without creating the
iterators.

Adam

--
Adam P. Jenkins
ajenkins@javanet.com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]





Author: "Adam P. Jenkins" <ajenkins@javanet.com>
Date: 1998/09/30
Raw View
obricker@my-dejanews.com wrote in message
<6ug90g$188$1@nnrp1.dejanews.com>...
>In article <6ubc90$tc8$1@nnrp1.dejanews.com>,
>  jkanze@otelo.ibmmail.com wrote:
>> error if the element already exists.  For some reason,
>>
>>     assert( myMap.find( key ) == myMap.end() ) ;
>>
>> just doesn't seem as clear as
>>
>>     assert( ! myMap.contains( key ) ) ;
>>
>
>Doesn't map.insert return a pair<iterator,bool> that tells wether it
succeeded
>or not?
>     assert(!(myMap.insert(myValuePair)).second);
>
>Well, I guess that is not any more clear than the ones above.


map::insert modifies the map by inserting a new key/value, whereas the first
examples only check if the map already contains an element, without
modifying it.

I agree, I believe it is an oversight for a map class not to have a
contains(key) method; I find the
    aMap.find(key) == aMap.end()
idiom to be tedious to write over and over, and less intuitive than
    aMap.contains(key)

Adam




      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/10/01
Raw View
On 30 Sep 1998 16:18:59 GMT, Adam P. Jenkins <ajenkins@javanet.com> wrote:

>I agree, I believe it is an oversight for a map class not to have a
>contains(key) method; I find the
>    aMap.find(key) == aMap.end()
>idiom to be tedious to write over and over, and less intuitive than
>    aMap.contains(key)

This func is not part of the minimal interface.  It can be implemented
maximally efficiently in terms of the other funcs.

--
----------------------------------
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              ]






Author: codemonkey_uk@hotmail.com (Code Monkey UK)
Date: 1998/09/29
Raw View
On 27 Sep 98 09:12:29 GMT, obricker@my-dejanews.com wrote:
>Doesn't map.insert return a pair<iterator,bool> that tells wether it succeeded
>or not?
>     assert(!(myMap.insert(myValuePair)).second);
>

Oops.  All of a sudden release build doesn't work.

NEVER EVER put non debug code inside an assert, it won't execute when
you do a release build and you'll have a hell of a time finding out
why.  When you get "release build only" bugs the first thing to do is
search for all "asserts" in your code and check that they don't
contain any code that has to execute in release build.  Like you've
done in the above example.

Thad.


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]





Author: Pete Becker <petebecker@acm.org>
Date: 1998/09/29
Raw View
obricker@my-dejanews.com wrote:
>
> Doesn't map.insert return a pair<iterator,bool> that tells wether it succeeded
> or not?
>      assert(!(myMap.insert(myValuePair)).second);
>
> Well, I guess that is not any more clear than the ones above.

It's also a misuse of assert. If you compile this code with NDEBUG
defined the insertion will not take place.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]





Author: obricker@my-dejanews.com
Date: 1998/09/29
Raw View
In article <360f73ea.8802097@news.demon.co.uk>,
  codemonkey_uk@hotmail.com (Code Monkey UK) wrote:
> On 27 Sep 98 09:12:29 GMT, obricker@my-dejanews.com wrote:
> >Doesn't map.insert return a pair<iterator,bool> that tells wether it
succeeded
> >or not?
> >     assert(!(myMap.insert(myValuePair)).second);
> >
>
> Oops.  All of a sudden release build doesn't work.

I can't believe I wrote that! Responding to newsgroups at the end of long days
is a habit I will have to break.

My point was that you can just insert and then test if it succeeded. I believe
that myMap should be unchanged if the key already exists. And if this is an
error, it is likely you would want the value of the existing element.

Otis B.
(I am so embarrassed)



-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ 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              ]






Author: jkanze@otelo.ibmmail.com
Date: 1998/09/24
Raw View
In article <MPG.106985169a577d5898a1a6@news.concentric.net>,
  brownsta@concentric.net (Stan Brown) wrote:

> 1. When you want to update an existing value only if the key exists, you
>
> have to first try a find(), compare the result not equal to end(), and
> only then assign the value. Why is there no function that updates the
> value if the key exists and does nothing if the key doesn't exist? The
> function could perhaps return a bool to distinguish the two cases.

My experience has been that trying to access with a key that doesn't
exist is usually an error.  When I wrote my own associative array class
(long before STL), I did the same as STL -- if you accessed an inexistant
key, an entry was created for it.  If I had it to do over, however, I
would make accessing an inexistant key an error.

The situation would be easier to handle if there were a contains function
in the map.  My associative arrays had one; they also had a cache with
the last hit, set by the contains function, which meant that accessing
with the same key was significantly faster.  I suspect that this is part
of the reasoning behind the way STL works.  A contains function must
do a look-up, and typically, if the look-up returns true, you immediately
access the same element.  By using find and getting the iterator, the
following access is in a very small constant time (whereas the initial
access is log n).

After getting used to it, the look-up idiom no longer bothers me, although
I would prefer that operator[] generated an error rather than implicitly
created.  I am still somewhat uncomfortable by the opposite case (which
I also find fairly frequent), where you are inserting, and it is an
error if the element already exists.  For some reason,

    assert( myMap.find( key ) == myMap.end() ) ;

just doesn't seem as clear as

    assert( ! myMap.contains( key ) ) ;

I suspect that it is largely a question of habit, however.  While contains
says what is says, things like comparing the results of find() to end()
will probably become enough of a standard idiom that people recognize
it for what it is.  (One of the nice things about defining a standard
is that whatever you do is, almost by definition, readable.  In any
single project, anyone suggesting something as wild as overloading the
left shift operator to mean formatting output data would be drawn and
quartered; the resulting code would just be to bizarre to be easily
readable.  The overload is standard, however, and anyone who doesn't
immediately recognize << as output hasn't programmed in C++.)

The standard forms thus become:

    template< class Map >
    void
    set( Map& m , Map::key_type key , Map::mapped_type value )
    {
        assert( m.find( key ) == m.end() ) ;
        m[ key ] = value ;
    }

    template< class Map >
    Map::mapped_type
    get( Map const& m , Map::key_type key )
    {
        assert( m.find( key ) != m.end() ) ;
        return const_cast< Map& >( m )[ key ] ;
    }

Both functions can be written more efficiently, I think.

> 2. To get the value associated with a given key, you have to acquire an
> iterator and then apply (*it).second. Why is there no templatized
> function to just return the value?

What's wrong with just operator[]?  (Except that it might accidentally
create a new element.)

One last point: it is far from certain that the decision to implicitly
create an element is wrong. I found that, statistically, I either wanted
to create (and it was an error if one existed) or I wanted to access (and
it was an error if none existed), but this only says something about the
uses in my applications.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ 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              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/09/27
Raw View
Darin Johnson wrote:
>
> "Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>
> > Some of the STL stuff, when instantiated for T* pointer types, may
> > convert into inline functions that wrap a single void* implementation in
> > the necessary casts. Thus, no more code is generated, at least for some
> > operations, even if you use lots of different T's. That kills one of the
> > prime advantages of an explicit container of void*.
>
> That's a moot point.  You can always write the container class to have
> inline member functions that give the same speed advantages for the
> common operations.
>
> Personally, I'd like to see a template wrapper around real generic
> Smalltalk like classes.  The template takes care of type checking,
> casting things back and forth from void*, whereas the class allows
> all the useful things you expect from classes.  (and of course
> the class has some inline member function, so no speed concerns)

How does that differ from a partial specialization of list<T*> that uses
an explicitily instantiated list<void*>?

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: obricker@my-dejanews.com
Date: 1998/09/27
Raw View
In article <6ubc90$tc8$1@nnrp1.dejanews.com>,
  jkanze@otelo.ibmmail.com wrote:
> After getting used to it, the look-up idiom no longer bothers me, although
> I would prefer that operator[] generated an error rather than implicitly
> created.  I am still somewhat uncomfortable by the opposite case (which
> I also find fairly frequent), where you are inserting, and it is an
> error if the element already exists.  For some reason,
>
>     assert( myMap.find( key ) == myMap.end() ) ;
>
> just doesn't seem as clear as
>
>     assert( ! myMap.contains( key ) ) ;
>

Doesn't map.insert return a pair<iterator,bool> that tells wether it succeeded
or not?
     assert(!(myMap.insert(myValuePair)).second);

Well, I guess that is not any more clear than the ones above.


Otis B.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/09/23
Raw View
On 22 Sep 1998 05:24:07 -0400, obricker@my-dejanews.com
>In article <MPG.106985169a577d5898a1a6@news.concentric.net>,

> > 1. When you want to update an existing value only if the key exists, you
> > have to first try a find(), compare the result not equal to end(), and
> > only then assign the value. Why is there no function that updates the
> > value if the key exists and does nothing if the key doesn't exist? The
> > function could perhaps return a bool to distinguish the two cases.

This func is not part of the minimal interface.  You can build it if you
want from the existing funcs.  However, your new func won't be a member,
or if you want it to be a member, you'll have to derive a new class from
std::map.


> > 2. To get the value associated with a given key, you have to acquire an
> > iterator and then apply (*it).second. Why is there no templatized
> > function to just return the value?

Good.

>Whats wrong with MyMap[key]? If the complaint is that this will create an
>element for the key if none exists, what would you have the function do if the
>key doesn't exist?

If the key doesn't exist, you throw an exception.
Therefore, operator[] non-const remains as is
How about a new func, operator[] const that throws an exception if key not found


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: jkanze@otelo.ibmmail.com
Date: 1998/09/18
Raw View
In article <MPG.1067565ad0b636b79896e3@netnews.worldnet.att.net>,
  Tony@ask.me (Tony) wrote:
>
> In article <35FBE38D.86F9219@rpi.edu>, osmanb@rpi.edu says...
>
> > Because it removes the burden of type-checking from the user of the
> > library, I'd say STL is definitely worth it. As for storing pointers in
> > containers, that's often done for reasons of polymorphism, in which case
> > using void * is going to be quite a bit more trouble. Unless you're
> > writing a compiler, what difference should it make to you? My compiler
> > can handle all of STL fine, and any other C++ compiler should be able to
> > as well. If not, it isn't a C++ compiler.
>
> Well if you want control of the object lifetime, you can't store the
> actual object in an STL container as it will be deleted when the
> container is, for instance.

If you are concerned about control over object lifetime, then you probably
don't want value semantics at all, will forbid copy and assignment, and
will instanciate the container over a reference counted pointer or
a registering pointer to the type, rather than the type itself.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: brownsta@concentric.net (Stan Brown)
Date: 1998/09/21
Raw View
Tom.Horsley@worldnet.att.net (Thomas A. Horsley) wrote:
>Just
>the other day, for instance, I had a perfect application for a "map",
but
>I couldn't for the life of me figure out how to update the value part
of
>an existing map entry.

mapVariable[x] = newY;

What gets me is that there seem to be two gaps in the design of map<>.
By
"gaps" I mean that carrying out these operations seems unnecessarily
complicated, to my naive mind at least.

If someone can tell me a direct one-step way to do either of the
following, I'll feel foolish for having missed it but at least I'll have

learned something. And if there's no one-step way to do these things,
perhaps someone who is familiar with the history could give some insight

into why these were thought unnecessary.

1. When you want to update an existing value only if the key exists, you

have to first try a find(), compare the result not equal to end(), and
only then assign the value. Why is there no function that updates the
value if the key exists and does nothing if the key doesn't exist? The
function could perhaps return a bool to distinguish the two cases.

2. To get the value associated with a given key, you have to acquire an
iterator and then apply (*it).second. Why is there no templatized
function to just return the value?

--
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA
                      http://www.concentric.net/%7eBrownsta/
My reply address is correct as is. The courtesy of providing a correct
reply address is more important to me than time spent deleting spam.


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]





Author: obricker@my-dejanews.com
Date: 1998/09/22
Raw View
In article <MPG.106985169a577d5898a1a6@news.concentric.net>,
  brownsta@concentric.net (Stan Brown) wrote:
 > Tom.Horsley@worldnet.att.net (Thomas A. Horsley) wrote:
 > >Just
 > >the other day, for instance, I had a perfect application for a "map",
 > but
 > >I couldn't for the life of me figure out how to update the value part
 > of
 > >an existing map entry.
 >
 > mapVariable[x] = newY;
 >
 > What gets me is that there seem to be two gaps in the design of map<>.
 > By
 > "gaps" I mean that carrying out these operations seems unnecessarily
 > complicated, to my naive mind at least.
 >
 > If someone can tell me a direct one-step way to do either of the
 > following, I'll feel foolish for having missed it but at least I'll have
 >
 > learned something. And if there's no one-step way to do these things,
 > perhaps someone who is familiar with the history could give some insight
 >
 > into why these were thought unnecessary.
 >
 > 1. When you want to update an existing value only if the key exists, you
 >
 > have to first try a find(), compare the result not equal to end(), and
 > only then assign the value. Why is there no function that updates the
 > value if the key exists and does nothing if the key doesn't exist? The
 > function could perhaps return a bool to distinguish the two cases.
 >
 > 2. To get the value associated with a given key, you have to acquire an
 > iterator and then apply (*it).second. Why is there no templatized
 > function to just return the value?

Whats wrong with MyMap[key]? If the complaint is that this will create an
element for the key if none exists, what would you have the function do if the
key doesn't exist?

Otis Bricker

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ 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              ]






Author: Chad Woodford <chad@tlogic.com>
Date: 1998/09/17
Raw View
You should check out the "STL Tutorial and Reference Guide" by Musser & Saini,
published by Addison Wesley.  It's a great book.

Chad

Thomas A. Horsley wrote:
> Nah! The only real problem with STL from my perspective is the utter lack
> of useful documentation (at least on the Microsoft VC++ docs). I suspect
> if I were to buy a good book, I would find them much more useful.

[ moderator's note: Excessive quoting deleted. Please only include
  relevant material in what you quote. -sdc ]


[ 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              ]






Author: scott@softbase.com
Date: 1998/09/17
Raw View
> Nah! The only real problem with STL from my perspective is the utter lack
> of useful documentation (at least on the Microsoft VC++ docs). I suspect
> if I were to buy a good book, I would find them much more useful.

I suggest you do this -- without a tutorial, you have no chance at
all to survive the STL. It isn't hard, it just takes getting
used to. The C++ Primer is a good intro.

> Just
> the other day, for instance, I had a perfect application for a "map", but
> I couldn't for the life of me figure out how to update the value part of
> an existing map entry.

Well, try:

 map[existing] = value;

with a string to string map, you say:

 map["string1"] = "string2";
 map["string1"] = "string3";

Java programmers should remember C++ has no garbage collection,
so if you have a map of pointers to something, you'll be in
trouble if you don't delete things.

Scott
--
Look at Softbase Systems' client/server tools, www.softbase.com
Check out the Essential 97 package for Windows 95 www.skwc.com/essent
All my other cool web pages are available from that site too!
My demo tape, artwork, poetry, The Windows 95 Book FAQ, and more.


[ 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              ]






Author: olczyk@interaccess.com (Thaddeus L. Olczyk)
Date: 1998/09/17
Raw View
On 14 Sep 98 11:33:30 GMT, Tom.Horsley@worldnet.att.net (Thomas A.
Horsley) wrote:

>Nah! The only real problem with STL from my perspective is the utter lack
>of useful documentation (at least on the Microsoft VC++ docs).

Try going to SGI's web site and downloading their manual.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ 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              ]






Author: Tony@ask.me (Tony)
Date: 1998/09/17
Raw View
In article <uyaro2qxo.fsf@worldnet.att.net>, Tom.Horsley@worldnet.att.net
says...

> >Now my worry with template containers is that they're too much complexity
> >to implement in a compiler.
>
> Nah!

Justify that plz.

Tony



[ 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              ]






Author: Tony@ask.me (Tony)
Date: 1998/09/17
Raw View
In article <35FBE38D.86F9219@rpi.edu>, osmanb@rpi.edu says...

> Because it removes the burden of type-checking from the user of the
> library, I'd say STL is definitely worth it. As for storing pointers in
> containers, that's often done for reasons of polymorphism, in which case
> using void * is going to be quite a bit more trouble. Unless you're
> writing a compiler, what difference should it make to you? My compiler
> can handle all of STL fine, and any other C++ compiler should be able to
> as well. If not, it isn't a C++ compiler.

Well if you want control of the object lifetime, you can't store the
actual object in an STL container as it will be deleted when the
container is, for instance.

Tony



[ 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              ]






Author: "Adam P. Jenkins" <ajenkins@javanet.com>
Date: 1998/09/17
Raw View
Scott Risdal wrote in message <35FEAA49.86E6DC83@superior.dul.epa.gov>...
>
>this is off the top of my head but one way to update with the map value:
..<snip>..
>// or I think
>phred.find("one").second    = 2;


Actually that would be

(*phred.find("one")).second    = 2;

Or in a truely conforming STL implementation where the iterators have ->,

phred.find("one")->second    = 2;

--
Adam P. Jenkins
ajenkins@javanet.com



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: jbuck@best.com (Joe Buck)
Date: 1998/09/15
Raw View
Thomas A. Horsley <Tom.Horsley@worldnet.att.net> wrote:
>Nah! The only real problem with STL from my perspective is the utter lack
>of useful documentation (at least on the Microsoft VC++ docs).

Point your browser to

 http://www.sgi.com/Technology/STL/

to find some excellent documentation.  (The only bad part is that the
documentation does not clearly mark SGI extensions ... if this were
done, the documentation would be more useful to those using other
implementations).

You would quickly be able to answer your question about maps.


--
-- Joe Buck
   work: jbuck@synopsys.com, otherwise jbuck@welsh-buck.org or jbuck@best.com
http://www.welsh-buck.org/


[ 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              ]






Author: Scott Risdal <srisdal@superior.dul.epa.gov>
Date: 1998/09/15
Raw View
this is off the top of my head but one way to update with the map value:

map<string, int>    phred;

// add a pair to the set.
phred["one"]    = 1;

// change the value
phred["one"]    = 2;

// or I think
phred.find("one").second    = 2;

I use "STL Tutorial and Reference Guide" by David Musser.

Scott

Thomas A. Horsley wrote:

> >Now my worry with template containers is that they're too much complexity
> >to implement in a compiler.
>
> Nah! The only real problem with STL from my perspective is the utter lack
> of useful documentation (at least on the Microsoft VC++ docs). I suspect
> if I were to buy a good book, I would find them much more useful. Just
> the other day, for instance, I had a perfect application for a "map", but
> I couldn't for the life of me figure out how to update the value part of
> an existing map entry. Do I have to delete the old entry and install
> a new one with a new value? Or can I just modify the value through the
> iterator returned by the lookup function? I can't tell these things. In
> the end, the effort required to figure it out became greater than the
> effort required to just write my own hash table :-).
> --
> >>==>> The *Best* political site <URL:http://www.vote-smart.org/> >>==+
>       email: Tom.Horsley@worldnet.att.net icbm: Delray Beach, FL      |
> <URL:http://home.att.net/~Tom.Horsley> Free Software and Politics <<==+

[ 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              ]






Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/09/16
Raw View
Tony wrote:
>
> Thank god the STL encapsulates things like red-black trees etc.  Now
> my worry with template containers is that they're too much complexity
> to implement in a compiler.  I'm going to compare STL against my good
> friend void* and see if the added complexity is worth it (most of my
> containers seem to store pointers anyway and not actual objects).  Is
> there a market for non-template containers?

Some of the STL stuff, when instantiated for T* pointer types, may
convert into inline functions that wrap a single void* implementation in
the necessary casts. Thus, no more code is generated, at least for some
operations, even if you use lots of different T's. That kills one of the
prime advantages of an explicit container of void*.

--

Ciao,
Paul


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: millette@bigfoot.com
Date: 1998/09/16
Raw View
Here are a few words from an STL novice , who would love to use it but is
getting bummed out by BC++ 4.51:

In article <uyaro2qxo.fsf@worldnet.att.net>,
  Tom.Horsley@worldnet.att.net (Thomas A. Horsley) wrote:
> >Now my worry with template containers is that they're too much complexity
> >to implement in a compiler.
>
> Nah! The only real problem with STL from my perspective is the utter lack
> of useful documentation (at least on the Microsoft VC++ docs). I suspect
> if I were to buy a good book, I would find them much more useful.

My only reference on STL is from David R. Musser and Atul Saini, "STL
Tutorial and Reference Guide". I've looked at a few sites too, which are
very informative, but I'm mostly learning from the book. I have a bunch of
other book from Addision-Wesley prof. comp. series, and find them most useful.

> Just
> the other day, for instance, I had a perfect application for a "map", but
> I couldn't for the life of me figure out how to update the value part of
> an existing map entry. Do I have to delete the old entry and install
> a new one with a new value? Or can I just modify the value through the
> iterator returned by the lookup function?

This might be wrong, because I'm not in a position to try it right now, but
as a test for my book's usefulness, I checked in the index for the word
"map", and under that, I found an entry: "element access member functions".
I turned to the page and found operator [] as a possible candidate. Here
are the prototypes: T& operator[] (const key_type& x) const T& operator[]
(const key_type& x) const

I figure this would do it:
mymap[key] = new_value;

Two things: if no element of type T associated with key x is found in
the map, then it's inserted.  Second thing: time bound is O(log N),
where N is the size of the map.

> I can't tell these things. In
> the end, the effort required to figure it out became greater than the
> effort required to just write my own hash table :-).

Another fine feature of the STL is the possibility of expanding it. For
instance, in the beginning, there's wasn't a hash in STL, but someone
made one, and he was careful to make it STL compatible. In that sense, once
you learn a few basic features of the STL for one kind of container, you've
covered the ground of all containers.

There, 0.02$ of a newbie :)

--
Fastest Computer on Earth needs you!
http://www.distributed.net - team 844

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: Tony@ask.me (Tony)
Date: 1998/09/12
Raw View
Thank god the STL encapsulates things like red-black trees etc.  Now my
worry with template containers is that they're too much complexity to
implement in a compiler.  I'm going to compare STL against my good friend
void* and see if the added complexity is worth it (most of my containers
seem to store pointers anyway and not actual objects).  Is there a market
for non-template containers?

Tony
 - C++ Lite emerges.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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              ]






Author: Brian Osman <osmanb@rpi.edu>
Date: 1998/09/14
Raw View
Because it removes the burden of type-checking from the user of the
library, I'd say STL is definitely worth it. As for storing pointers in
containers, that's often done for reasons of polymorphism, in which case
using void * is going to be quite a bit more trouble. Unless you're
writing a compiler, what difference should it make to you? My compiler
can handle all of STL fine, and any other C++ compiler should be able to
as well. If not, it isn't a C++ compiler.

-Brian


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]





Author: Tom.Horsley@worldnet.att.net (Thomas A. Horsley)
Date: 1998/09/14
Raw View
>Now my worry with template containers is that they're too much complexity
>to implement in a compiler.

Nah! The only real problem with STL from my perspective is the utter lack
of useful documentation (at least on the Microsoft VC++ docs). I suspect
if I were to buy a good book, I would find them much more useful. Just
the other day, for instance, I had a perfect application for a "map", but
I couldn't for the life of me figure out how to update the value part of
an existing map entry. Do I have to delete the old entry and install
a new one with a new value? Or can I just modify the value through the
iterator returned by the lookup function? I can't tell these things. In
the end, the effort required to figure it out became greater than the
effort required to just write my own hash table :-).
--
>>==>> The *Best* political site <URL:http://www.vote-smart.org/> >>==+
      email: Tom.Horsley@worldnet.att.net icbm: Delray Beach, FL      |
<URL:http://home.att.net/~Tom.Horsley> Free Software and Politics <<==+


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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              ]