Modify STL map Object

M

Mike Copeland

The following program does not update the STL map object on the 2nd
call to "find" it. That is, I find the object after I've stored it, I
modify an object - but when I try to (re)insert it the map object isn't
changed. Please advise. TIA

#pragma warning (disable:4786)
#include <map>
#include <string>
#include <time.h>

using namespace std;

typedef struct ChipRec
{
int bibNum;
short dbeAge, ndfAge, gruAge;
short dbeGender, ndfGender, gruGender;
char dbeRCode, ndfRCode, gruRCode;
char entECode;
bool timeWritten;
bool dbeMatched, ndfMatched, gruMatched;
bool dbeLoaded, ndfLoaded, gruLoaded;
string dbeName, gruName;
string ctsKey;
string teamId;
} tData;
tData tWork, qWork;

typedef map<int, ChipRec> BCI;
BCI bci;
map<int, ChipRec>::iterator bciIter;
int bibNumber = 11;
int main()
{
bci.clear();
tWork.dbeGender = tWork.gruGender = tWork.ndfGender = 'M';
tWork.dbeAge = tWork.gruAge = tWork.ndfAge = 47;
tWork.dbeRCode = tWork.gruRCode = tWork.ndfRCode = 'a';
tWork.dbeName = "George Washington";
tWork.teamId = "NONE";
tWork.ctsKey = "PXZ";
tWork.entECode = 'A';
tWork.bibNum = bibNumber;
tWork.gruMatched = tWork.ndfMatched = false;
tWork.gruLoaded = tWork.ndfLoaded = false;
tWork.timeWritten = false;
tWork.dbeLoaded = true;
bci.insert(BCI::value_type(bibNumber, tWork));

int bibNum = 11;
map<int, ChipRec>::const_iterator wIter;
wIter = bci.find(bibNum);
if(wIter != bci.end())
{
qWork = wIter->second;
qWork.dbeAge = 74, qWork.dbeName = "Abe Lincoln";
bci.insert(BCI::value_type(bibNumber, qWork));
}
wIter = bci.find(bibNum);
if(wIter != bci.end())
{
tWork = wIter->second;
}

return 0;
}
 
I

Ian Collins

The following program does not update the STL map object on the 2nd
call to "find" it. That is, I find the object after I've stored it, I
modify an object - but when I try to (re)insert it the map object isn't
changed. Please advise. TIA

#pragma warning (disable:4786)
#include<map>
#include<string>
#include<time.h>

using namespace std;

typedef struct ChipRec

This is the C way of declaring a struct.
{
int bibNum;
short dbeAge, ndfAge, gruAge;
short dbeGender, ndfGender, gruGender;
char dbeRCode, ndfRCode, gruRCode;
char entECode;
bool timeWritten;
bool dbeMatched, ndfMatched, gruMatched;
bool dbeLoaded, ndfLoaded, gruLoaded;
string dbeName, gruName;
string ctsKey;
string teamId;
} tData;
tData tWork, qWork;

typedef map<int, ChipRec> BCI;
BCI bci;
map<int, ChipRec>::iterator bciIter;
int bibNumber = 11;
int main()
{
bci.clear();
tWork.dbeGender = tWork.gruGender = tWork.ndfGender = 'M';
tWork.dbeAge = tWork.gruAge = tWork.ndfAge = 47;
tWork.dbeRCode = tWork.gruRCode = tWork.ndfRCode = 'a';
tWork.dbeName = "George Washington";
tWork.teamId = "NONE";
tWork.ctsKey = "PXZ";
tWork.entECode = 'A';
tWork.bibNum = bibNumber;
tWork.gruMatched = tWork.ndfMatched = false;
tWork.gruLoaded = tWork.ndfLoaded = false;
tWork.timeWritten = false;
tWork.dbeLoaded = true;
bci.insert(BCI::value_type(bibNumber, tWork));

int bibNum = 11;
map<int, ChipRec>::const_iterator wIter;
wIter = bci.find(bibNum);
if(wIter != bci.end())
{
qWork = wIter->second;
qWork.dbeAge = 74, qWork.dbeName = "Abe Lincoln";
bci.insert(BCI::value_type(bibNumber, qWork));

Check the return from insert, you already have an item with the key
value of 11 in your map.
 
J

Juha Nieminen

Daniel T. said:
There are several issues with your code, but in the interest of brevity,
I will concentrate on your question. map::insert only inserts an object
if it doesn't already exist. Otherwise, you are expected to modify the
object that is already in place.

That's why std::map::eek:perator[] is so handy. It allows you to insert
a new key/value pair or, if a key already existed, to modify the value,
in one single statement. Eg:

myMap["hello"] = 5;

If a key with the value "hello" didn't exist, it will be inserted and
its value will be set to 5. If it existed, the existing value will be
changed to 5.
 
J

Juha Nieminen

Daniel T. said:
Juha Nieminen said:
Daniel T. said:
There are several issues with your code, but in the interest of brevity,
I will concentrate on your question. map::insert only inserts an object
if it doesn't already exist. Otherwise, you are expected to modify the
object that is already in place.

That's why std::map::eek:perator[] is so handy. It allows you to insert
a new key/value pair or, if a key already existed, to modify the value,
in one single statement. Eg:

myMap["hello"] = 5;

If a key with the value "hello" didn't exist, it will be inserted and
its value will be set to 5. If it existed, the existing value will be
changed to 5.

Just keep in mind, every time you use op[] you are doing a logarithmic
search

So do std::map::find() and std::map::insert(). So what?
and in this case, if the element didn't already exist, the OP
did seem to want to add it so op[] would be inappropriate.

I don't understand. operator[] *does* add the element if it didn't
exist.
 
J

Juha Nieminen

Daniel T. said:
Just keep in mind, every time you use op[] you are doing a
logarithmic search

So do std::map::find() and std::map::insert(). So what?

Calling find once is better than calling op[] multiple times.

And calling operator[] once is better than calling find() multiple times.
So what?

Maybe your point is that it's too easy to just call operator[] every
time you need to access an element, even when you are accessing the
same element many times in succession, whereas find() is telling more
explicitly that a "find this element in the tree" operation will be
performed, thus in a way "warning" the programmer that it's not an
extremely quick operation. operator[] resembles array indexing, which
might give the wrong impression that it's a constant-time operation.

Ok, fair enough. Of course you should know what the operator[] is
doing, and if you want to make repeated operations to the same element,
you should use a reference (ie. "type& element = theMap[value];" and
then use 'element' for the multiple operations).

However, std::map::eek:perator[] is still handier than find()+insert()
when what you want is automatic insertion if the element doesn't exist.
I don't understand. operator[] *does* add the element if it didn't
exist.

What if you don't want to add the element if it doesn't exist?

Your original point was about insert(), and how it doesn't when the
element already exists, to which I pointed out that operator[] is much
handier for that purpose.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top