Re: stl::map: return default value without inserting a new element?
Rui Maciel wrote:
When using STL's map container, if operator[] is used to access the value
associated with a given key which wasn't inserted then a new key:value
pair will be created and a reference to
the value will be returned. This means that, although operator[] is a
convenient way to add new key:value pairs to a map, it may end up
needlessly adding useless key:value pairs into the map.
In order to avoid wasting resources populating a map with useless
key:value pairs, is there a clean, unencumbered way to get the value
associated with a given key without being forced to
insert new elements or even resort to multiple lines of code? The closest
thing I saw was the map::find() method, but I believe that ends up forcing
to write code to compare the given iterator to map::end() and, if it
matches, return a default value.
Is there a simpler way to do this?
Not really. You can, of course, wrap this little thing into a dictionary
class, which internally uses a map and find(). But that is not provided by
the standard. Here is what I use:
template < typename KeyType, typename MappedType >
class dictionary {
typedef std::map< KeyType, MappedType > map_type;
map_type the_map;
MappedType the_default;
public:
typedef KeyType key_type;
typedef MappedType mapped_type;
dictionary ( mapped_type const & val = mapped_type() )
: the_map ()
, the_default ( val )
{}
dictionary & insert ( key_type const & key,
mapped_type const & val ) {
the_map[ key ] = val;
return ( *this );
}
dictionary & erase ( key_type const & key ) {
the_map.erase( key );
return( *this );
}
mapped_type const &
operator() ( key_type const & key ) const {
typename map_type::const_iterator iter =
the_map.find( key );
if ( iter == the_map.end() ) {
return ( the_default );
}
return ( iter->second );
}
};
The insert() and erase() method allow for chaining.
Best
Kai-Uwe Bux