Map problems

J

Joe Laughlin

I have this snippet of code. Let me know if I need to give more for
feedback:

typedef std::map<const char*, float> AttitudeRecord;

// player_info.GetAttitude should return an AttitudeRecord with
// key: roll value: 34
// key: pitch value: 598
// key: attitude value: 34
AttitudeRecord atttiude = player_info.GetAttitude();

AttitudeRecord::iterator iter;
iter = attitude.find("pitch");

// This prints out a completely wrong value! Why?
std::cout << "Value of pitch: " << attitude->second;

// This loop prints what seems to be the correct values
for (iter = attitude.begin(); iter != attitude.end(); ++iter)
{
std::cout << "\nKey: " << iter->first << " Value: " << iter->second;
}




Output:

Value of pitch: 3893.33 (Wrong!)
Key: roll Value: 34
Key: pitch Value: 598
Key: heading Value: 34


What I really want to do is easily get to the value of a specific key. But
I can't seem to find a way to do it.
 
J

John Harrison

Joe Laughlin said:
I have this snippet of code. Let me know if I need to give more for
feedback:

typedef std::map<const char*, float> AttitudeRecord;

// player_info.GetAttitude should return an AttitudeRecord with
// key: roll value: 34
// key: pitch value: 598
// key: attitude value: 34
AttitudeRecord atttiude = player_info.GetAttitude();

AttitudeRecord::iterator iter;
iter = attitude.find("pitch");

// This prints out a completely wrong value! Why?
std::cout << "Value of pitch: " << attitude->second;

Presumably you mean iter->second.

The problem is that you have a map whose keys are pointers. So lookup is
done by comparing pointers, not by comparing strings, which I think is what
you are assuming. Presumably in this case the pointer you use to lookup the
record is not *precisely* the same pointer you used to add the record.

Simple answer is to use real strings

typedef std::map<std::string, float> AttitudeRecord;

which apart from solving your specific problem also has other advantages
namely making memory management much easier.

But if for some reason you must stick with pointers then you must provide a
comparison functor

struct StringLessThan
{
bool operator()(const char* a, const char* b) const
{
return strcmp(a, b) < 0;
}
};

typedef std::map<std::string, float, StringLessThan> AttitudeRecord;


john
 
J

John Harrison

But if for some reason you must stick with pointers then you must provide a
comparison functor

struct StringLessThan
{
bool operator()(const char* a, const char* b) const
{
return strcmp(a, b) < 0;
}
};

typedef std::map<std::string, float, StringLessThan> AttitudeRecord;

Sorry, cut and paste error, I meant this

typedef std::map<const char*, float, StringLessThan> AttitudeRecord;

john
 
J

Joe Laughlin

John said:
Presumably you mean iter->second.

Doh, I did.
The problem is that you have a map whose keys are
pointers. So lookup is done by comparing pointers, not by
comparing strings, which I think is what you are
assuming. Presumably in this case the pointer you use to
lookup the record is not *precisely* the same pointer you
used to add the record.

Simple answer is to use real strings

typedef std::map<std::string, float> AttitudeRecord;

I'll try that. I was just going off some examples I found, and they used
const char*. When I first started, I used std::string, but I ran into some
troubles that using const char* worked instead.
 
J

Joe Laughlin

Joe said:
Doh, I did.


I'll try that. I was just going off some examples I
found, and they used const char*. When I first started,
I used std::string, but I ran into some troubles that
using const char* worked instead.

Doh, my problems were that I didn't include the string header. I hate
computers.
 

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

Members online

Forum statistics

Threads
474,173
Messages
2,570,938
Members
47,473
Latest member
pioneertraining

Latest Threads

Top