473,404 Members | 2,137 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

Template to insert into a map? Is this really necessary?

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;

My map is fairly simple.

std::map<std::string, DropdownBoxDropdowns;

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_pair<K,
D>( Key, Data ) );
return it->second;
}

The usage:

DropdownBox& ThisBox = InsertToMap( std::string("RoteDots"), DropdownBox(
Parent, IDC_RoteDots ), Dropdowns );

which even though still a bit ugly, is better than the first one IMO.

Of course I could always insert into the map then use .find() but I've
alwasy found that bothersome in itself.

Any opionions?
Jul 5 '07 #1
7 3163
On Jul 5, 12:49 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
template<class K, class D>
D& InsertToMap( K& Key, D& Data, std::map<K, D>& Map )

The usage:

DropdownBox& ThisBox = InsertToMap( std::string("RoteDots"),
DropdownBox(Parent, IDC_RoteDots ), Dropdowns );
This is an error; you can't bind a temporary to
a non-const reference. Either switch your compiler
to conforming mode, or post your exact code.

Also, why would you want to return a reference
to the input data. It doesn't make any logical
sense to do anything with it once a copy of it
has been put into the map.
which even though still a bit ugly, is better than the first one
You seem to have omitted trying:
Dropdowns.insert( std::make_pair(
std::string("RoteDots"), DropDownBox( Parent, IDC_RoteDots ) ) );

(the whole point of std::make_pair is that you do
not explicitly specify the template parameters).

If you dont mind using a function then the obvious is
(replace Ddmap with the typedef you've defined for
your map):
void insert_dropdown( Ddmap &map,
Ddmap::key_type const &key, Ddmap::value_type const &value )
{
map.insert( std::make_pair(key, value) );
}

and then call:
insert_map( Dropdowns, "RoteDots, DropDownBox(foo,bar) );

You could even go as far as:
void insert_dropdown( Ddmap &map,
Ddmap::key_type const &key, Foo *foo, Bar *bar )
{
map.insert( std::make_pair(key, DropdownBox(foo,bar)) );
}

Jul 5 '07 #2

"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11**********************@i13g2000prf.googlegr oups.com...
On Jul 5, 12:49 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
>template<class K, class D>
D& InsertToMap( K& Key, D& Data, std::map<K, D>& Map )

The usage:

DropdownBox& ThisBox = InsertToMap( std::string("RoteDots"),
DropdownBox(Parent, IDC_RoteDots ), Dropdowns );

This is an error; you can't bind a temporary to
a non-const reference. Either switch your compiler
to conforming mode, or post your exact code.
Dang, I forgot to change from Warning level 3 to Warning level 4 when I
created this project. With W4 it does indeed say it's non conforming. Hmm.
Also, why would you want to return a reference
to the input data. It doesn't make any logical
sense to do anything with it once a copy of it
has been put into the map.
Because I am creating the instance in the map, then I need to do things with
it (add entries, etc..).
I.E.
DropdownBox& RoteDots = InsertToMap( Dropdowns, std::string("RoteDots"),
DropdownBox( Parent, IDC_RoteDots ) );
RoteDots.AddEntry( "0" );
RoteDots.AddEntry( "1" );
RoteDots.AddEntry( "2" );
RoteDots.AddEntry( "3" );
RoteDots.AddEntry( "4" );
RoteDots.AddEntry( "5" );
>which even though still a bit ugly, is better than the first one

You seem to have omitted trying:
Dropdowns.insert( std::make_pair(
std::string("RoteDots"), DropDownBox( Parent, IDC_RoteDots ) ) );

(the whole point of std::make_pair is that you do
not explicitly specify the template parameters).
I can fix that in my template.
If you dont mind using a function then the obvious is
(replace Ddmap with the typedef you've defined for
your map):
void insert_dropdown( Ddmap &map,
Ddmap::key_type const &key, Ddmap::value_type const &value )
{
map.insert( std::make_pair(key, value) );
}

and then call:
insert_map( Dropdowns, "RoteDots, DropDownBox(foo,bar) );

You could even go as far as:
void insert_dropdown( Ddmap &map,
Ddmap::key_type const &key, Foo *foo, Bar *bar )
{
map.insert( std::make_pair(key, DropdownBox(foo,bar)) );
}
Well, without the need to retrieve a reference to the added entry, it is
eaiser by a lot of ways, but I need to retrieve a reference to the entry
just added.
Jul 5 '07 #3
On Jul 5, 2:09 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
"Old Wolf" <oldw...@inspire.net.nzwrote in message
DropdownBox& ThisBox = InsertToMap( std::string("RoteDots"),
DropdownBox(Parent, IDC_RoteDots ), Dropdowns );
This is an error; you can't bind a temporary to
a non-const reference. Either switch your compiler
to conforming mode, or post your exact code.

Dang, I forgot to change from Warning level 3 to Warning level 4 when I
created this project. With W4 it does indeed say it's non conforming. Hmm.
You should actually fix this (i.e. make the function
take its new key and value by const reference).
You could even go as far as:
void insert_dropdown( Ddmap &map,
Ddmap::key_type const &key, Foo *foo, Bar *bar )
{
map.insert( std::make_pair(key, DropdownBox(foo,bar)) );
}

Well, without the need to retrieve a reference to the added entry, it is
eaiser by a lot of ways, but I need to retrieve a reference to the entry
just added.
return map.insert(....)->second;

Jul 5 '07 #4

"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11**********************@e16g2000pri.googlegr oups.com...
On Jul 5, 2:09 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
>"Old Wolf" <oldw...@inspire.net.nzwrote in message
>DropdownBox& ThisBox = InsertToMap( std::string("RoteDots"),
DropdownBox(Parent, IDC_RoteDots ), Dropdowns );
This is an error; you can't bind a temporary to
a non-const reference. Either switch your compiler
to conforming mode, or post your exact code.

Dang, I forgot to change from Warning level 3 to Warning level 4 when I
created this project. With W4 it does indeed say it's non conforming.
Hmm.

You should actually fix this (i.e. make the function
take its new key and value by const reference).
I did.
You could even go as far as:
void insert_dropdown( Ddmap &map,
Ddmap::key_type const &key, Foo *foo, Bar *bar )
{
map.insert( std::make_pair(key, DropdownBox(foo,bar)) );
}

Well, without the need to retrieve a reference to the added entry, it is
eaiser by a lot of ways, but I need to retrieve a reference to the entry
just added.

return map.insert(....)->second;
Well, that's what I'm doing. Although I am saving to an iterator first then
returning ->second
Jul 5 '07 #5
On Jul 5, 2:49 am, "Jim Langston" <tazmas...@rocketmail.comwrote:
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, DropdownBoxDropdowns;
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_pair<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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 5 '07 #6
"James Kanze" <ja*********@gmail.comwrote in message
news:11*********************@q69g2000hsb.googlegro ups.com...
On Jul 5, 2:49 am, "Jim Langston" <tazmas...@rocketmail.comwrote:
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.
If you don't give an iterator as the first parameter, a different .insert is
called which returns a value instead of an iterator. I needed the iterator,
so gave it an iterator.
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.
Most of the time I would too. In this particular case, I didn't care. I
didn't even really care what iterator it gave me with as a result. I knew
they were unique values.

[Snip the rest]

The funny thing is, after I implented this, and finished my program, I
realized I never once searched for the key. And then I realized a structure
would be better to hold the instances than a map :/ So I deleted the
template and everything associated with it.
Jul 7 '07 #7
On Jul 7, 12:57 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:11*********************@q69g2000hsb.googlegro ups.com...
On Jul 5, 2:49 am, "Jim Langston" <tazmas...@rocketmail.comwrote:
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.
If you don't give an iterator as the first parameter, a
different .insert is called which returns a value instead of
an iterator. I needed the iterator, so gave it an iterator.
The "value type" returned is an std::pair, with the iterator as
first element. You still get the iterator.
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.
Most of the time I would too. In this particular case, I
didn't care. I didn't even really care what iterator it gave
me with as a result. I knew they were unique values.
In which case, you can always assert that the second element of
the pair returned is true. (Or just ignore it.)

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 7 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Dave Rahardja | last post by:
OK, so I've gotten into a philosophical disagreement with my colleague at work. He is a proponent of the Template Method pattern, i.e.: class foo { public: void bar() { do_bar(); } protected:...
6
by: Ben Ingram | last post by:
Hi all, I am writing a template matrix class in which the template parameters are the number of rows and number of columns. There are a number of reasons why this is an appropriate tradeoff for...
31
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will...
5
by: nifsmith | last post by:
Hi I am trying to learn about Queues and use templates at the same time. I have written the following code and I am getting a link error, stating "unresolved external symbol, "int__cdecl...
5
by: Steve | last post by:
Hi, Does C++ allow the programmer to declare a template with in a template so that a generic function can instantiate the embedded template? For example, could code such as this exist: ...
4
by: Fei Liu | last post by:
#include <vector> #include <iostream> template <template <typename T, typename Allocclass C> struct A{ //C<Tc; //A(){ c=10; } void print(){ std::cout << "A" << std::endl; } };
45
by: charles.lobo | last post by:
Hi, I have recently begun using templates in C++ and have found it to be quite useful. However, hearing stories of code bloat and assorted problems I decided to write a couple of small programs...
4
by: Stephan Rose | last post by:
Hi everyone, I have a little problem I'm not sure what to do about or if anything can even be done about it. Situation is as follows: I had previous implemented a class called Scalar that...
4
by: suman.nandan | last post by:
Hi C++ Experts ! I have a little weird requirement. I have a base class, say B and lots of classes D1 .. Dn publicly derived from it. Over the course of development the number of derived...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.