Topic: hash_map in C++PL3


Author: bkline@nlm.nih.gov (Bob Kline)
Date: 1997/09/17
Raw View
This is a re-post of a couple of questions I've tried in a couple of
other forums without any responses.  The questions are about the
hash_map class in the new (3rd) edition of Bjarne Stroustrup's C++
Programming Language.  Since the questions are closely linked with the
draft standard, and since most of the really knowledgeable folks hang
out in this newsgroup, I'm hopeful I'll get at least one useful
response this time.  To increase my chances of getting a response,
let me encourage anyone who knows the answer to one of the two
but not the other to please jump right in.

The first of the two puzzles has to do with the specialization of the
hashing functor, whose class definition is given in 17.6.2.3 as:

template<class T> struct Hash : unary_function<T, size_t> {
    size_type operator()(const T& key) const;
};

After a definition of the common implementation for the operator() member
function, the text goes on to say, "A C-style string is a pointer (to the
characters), and a string contains a pointer.  Consequently,
specializations are in order:

size_t Hash<char*>::operator()(const char* key) const
{
    ....
}
...."

It would seem, however, that for Hash<char*> the argument for the function
would be char* const&, and that the version given above will make the
compiler think we are trying to overload the operator() function, but
without a prototype in the class definition.  Or am I missing something
about the language which would allow something along the same lines as the
overload resolution rules (which I admit I haven't mastered yet) to cause
this to be indeed matched up as a specialization?  None of the compilers
I've tried this on are willing to compile the code as written (though I am
aware that this is not conclusive evidence of anything).  The value of the
specialization would be greatly diminished, I should think, if 'const' has
to apply to the pointer instead of the chars being pointed to (meaning it
couldn't be used for const char* pointers), but I don't see any way around
it given my (limited) understanding of how template specializations are
supposed to work.

The other problem I'm having is with the iterators.  It seems unclear what
the caller of hash_map<T>::find() would be able to do with the iterator
which is returned.  No definition is given for iterator or const_iterator
in the pieces of the hash_map class definition which appear throughout the
section, but it would appear to be a synonym of 'pointer to Entry' since in
the definition of hash_map::erase(iterator p) p is used to get to the
'erased' member of Entry.  Giving the user of the hash_map class unlimited
access to the Entry structure, which is down in the bowels of the
implementation, doesn't seem like an attractive option.

The partial class definition given at the top of page 498 leads the reader
back to the map class ("class hash_map { // like map, except: ....").  The
descriptions and examples for the map class make it clear that the user is
supposed to treat the iterators as pointers to pair<const Key, mapped_type>
elements, gaining access to the key and mapped value of each element
through the names "first" and "second."  I can't see how it would be
possible to leap from 'pointer to Entry' to 'pointer to pair<const Key,
mapped_type>' except by something as roundabout as overloading
iterator::operator->(), which would defeat the code in hash_map::erase(),
since that code needs access to the original Entry structure.  I suspect
that he originally intended to provide some additional guidance in the
Exercises section, since this was alluded to in the last sentence of page
503, but unfortunately the exercise to which this sentence refers deals
with classes related to hash_map, not to the remainder of the
implementation of hash_map itself.

Thanks very much for any light the gurus can shed on these two.

--
Bob Kline
E:bob_kline@corpsoft.com
V:703.522.0820 x-311
F:703.522.5407
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/09/18
Raw View
Bob Kline <bkline@nlm.nih.gov> writes:

 > Since the questions are closely linked with the
 > draft standard, and since most of the really knowledgeable folks hang
 > out in this newsgroup, I'm hopeful I'll get at least one useful
 > response this time.

Both comp.std.c++ and comp.lang.c++.moderated seem appropriate (but
not both).

 > The first of the two puzzles has to do with the specialization of the
 > hashing functor, whose class definition is given in 17.6.2.3 as:
 >
 > template<class T> struct Hash : unary_function<T, size_t> {
 >     size_type operator()(const T& key) const;
 > };
 >
 > After a definition of the common implementation for the operator() member
 > function, the text goes on to say, "A C-style string is a pointer (to the
 > characters), and a string contains a pointer.  Consequently,
 > specializations are in order:
 >
 > size_t Hash<char*>::operator()(const char* key) const
 > {
 >     ....
 > }
 > ...."

I have been told that there were many typos in this book.

I think that you discovered one; it should be:

size_t Hash<char*>::operator()(char* const& key) const { ...

size_t Hash<const char*>::operator()(const char* const& key) const { ...

'Hash<char*> ... (const char*)' is an horrible mixture of the two.
Both specialisations are needed, as you may want to store char* in
a hast_table.

 > It would seem, however, that for Hash<char*> the argument for the function
 > would be char* const&, and that the version given above will make the
 > compiler think we are trying to overload the operator() function, but
 > without a prototype in the class definition.

I agree (but perhpas I missed something about specialisation too).

If the fact that it's a typo is confirmed, then someone should
tell Bjarne.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]