Re: Template to insert into a map? Is this really necessary?
On Jul 5, 2:49 am, "Jim Langston" <tazmas...@rocketmail.com> wrote:
I'm working on a program, and at one time I find it necessary to load
classes into a map. Now, these classes don't have default constructors, =
so
I can't retrieve them using
MyMap[MyKey].
So I wound up with a real ugly line:
DropdownBox& ThisBox = (Dropdowns.insert( Dropdowns.begin(),
std::make_pair<std::string, DropdownBox>( "RoteDots", DropdownBox( Parent,
IDC_RoteDots ) ) ))->second;
Just curious, but why the iterator argument? It's only a hint,
and only helps if the insertion occurs immediately in front of
it---in this case, if the new element will be the first element.
Most of the type, I'll have the map typedef'ed, and use its
value type:
typedef std::map< std::string, DropdownBox >
DDBoxMap ;
// ...
DropdownBox& thisBox = dropdowns.insert(
DDBoxMap::value_type(
"RoteDots",
DropdownBox( Parent,
IDC_RoteDots ) )
.first->second ;
Of course, most of the time, I'll also want to know if the
insertion succeeded.
My map is fairly simple.
std::map<std::string, DropdownBox> Dropdowns;
Well, I tried to improve it a little, and came up with
std::map<std::string, DropdownBox>::iterator it = Dropdowns.insert(
Dropdowns.begin(), std::make_pair<std::string, DropdownBox>( "RoteDots",
DropdownBox( Parent, IDC_RoteDots ) ) );
DropdownBox& ThisBox = it->second;
but that's still ugly. So I decided to make a template
function to help. The template itself is kinda messy, but
makes the code easier.
The template:
template<class K, class D>
D& InsertToMap( K& Key, D& Data, std::map<K, D>& Map )
{
std::map<K, D>::iterator it = Map.insert( Map.begin(), std::make_pa=
ir<K,
D>( Key, Data ) );
return it->second;
}
The real question is: what should the behavior be if the object
is already there: an error, use the already existing object, or
replace it with the new one. For the first two, you can base
your behavior on the return value of insert:
template< typename Key, typename Value >
Value&
insertIntoMap(
std::map< Key, Value >&
map,
Key const& key,
Value const& value )
{
typedef std::map< Key, Value >
Map ;
std::pair< Map::iterator, bool >
result
= map.insert( Map::value_type( key, value ) ) ;
if ( ! result.second ) {
// error handling, or
// result.first->second = value ;
// to set the new value.
// Drop the if to use the existing value.
}
return result.first->second ;
}
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34