maps turn into multimaps

B

brad

Erik said:
Of course not, if they did they would be multimaps and not maps.

I have a map that behaves as if it were a multimap. Two keys are the
same. Compiles and runs as expected.
 
B

brad

brad said:
I have a map that behaves as if it were a multimap. Two keys are the
same. Compiles and runs as expected.

Wait... perhaps I misundersatnd maps. Is it unique k,v pairs or just
unique keys? If it's the former, then that would make sense. I was under
the impression it was the latter.
 
P

peter koch

Wait... perhaps I misundersatnd maps. Is it unique k,v pairs or just
unique keys? If it's the former, then that would make sense. I was under
the impression it was the latter.

It is unique key, of course. You most likely have a bug in the
comparison function. Show some code if you want more help.

/Peter
 
E

Erik Wikström

Wait... perhaps I misundersatnd maps. Is it unique k,v pairs or just
unique keys? If it's the former, then that would make sense. I was under
the impression it was the latter.

It is the latter, if you insert a k,v pair and the key already exists it
will be returned (or rather an iterator to it). If you use the
operator[] to insert you will overwrite the existing element.
 
B

brad

peter said:
It is unique key, of course. You most likely have a bug in the
comparison function. Show some code if you want more help.

/Peter

It's a test for credit card pre-validation. I added 13 digit visa cards
to the test in addition to the more common 16 digit visa. The prefix for
all visas is "4" (which I use as the key). See below. As I said, it
works, I was just trying to better understand *why* it works :)

struct card_info
{
std::string card_name;
int card_length;
};


typedef std::map<std::string, card_info> cMap;
cMap card_map;

// VISA info
card_info v;
v.card_name = "Visa";
v.card_length = 16;
card_map.insert(std::pair<std::string, card_info>("4", v));

// VISA13 info
card_info v13;
v13.card_name = "Visa";
v13.card_length = 13;
card_map.insert(std::pair<std::string, card_info>("4", v13));

This insert works at compile time and there are no erros at run time, I
can pre-validate either 16 or 13 digit visa cards based on the above info.
 
B

brad

peter said:
It is unique key, of course. You most likely have a bug in the
comparison function. Show some code if you want more help.

/Peter

I might also note that this reference:

http://www.cppreference.com/cppmap/index.html

Indicates unique "key/value pairs". I was surprised to read that. It's
incorrect... if indeed we are talking about unique keys:

"C++ Maps are sorted associative containers that contain unique
key/value pairs."
 
P

peter koch

It's a test for credit card pre-validation. I added 13 digit visa cards
to the test in addition to the more common 16 digit visa. The prefix for
all visas is "4" (which I use as the key). See below. As I said, it
works, I was just trying to better understand *why* it works :)

struct card_info
   {
   std::string card_name;
   int card_length;
   };

  typedef std::map<std::string, card_info> cMap;
  cMap card_map;

   // VISA info
   card_info v;
   v.card_name = "Visa";
   v.card_length = 16;
   card_map.insert(std::pair<std::string, card_info>("4", v));

   // VISA13 info
   card_info v13;
   v13.card_name = "Visa";
   v13.card_length = 13;
   card_map.insert(std::pair<std::string, card_info>("4", v13));

You do not validate that the insert succeeds - this is most likey your
problem.

/Peter
 
B

brad

peter said:
You do not validate that the insert succeeds - this is most likey your
problem.

/Peter

Very good... the insert did fail. I'll have to look at this closer. 13
digit cards should not be validating, but they are. There's a bug some
place else (outside of the map code).

Thanks,

Brad
 
L

LR

brad said:
It's a test for credit card pre-validation. I added 13 digit visa cards
to the test in addition to the more common 16 digit visa. The prefix for
all visas is "4" (which I use as the key). See below. As I said, it
works, I was just trying to better understand *why* it works :)

struct card_info
{
std::string card_name;
int card_length;
};


typedef std::map<std::string, card_info> cMap;
cMap card_map;

// VISA info
card_info v;
v.card_name = "Visa";
v.card_length = 16;
card_map.insert(std::pair<std::string, card_info>("4", v));

// VISA13 info
card_info v13;
v13.card_name = "Visa";
v13.card_length = 13;
card_map.insert(std::pair<std::string, card_info>("4", v13));

This insert works at compile time and there are no erros at run time, I
can pre-validate either 16 or 13 digit visa cards based on the above info.

I'm not sure that I follow what you're trying to do here.

Suppose that you have a ctor for card_info,

card_info::card_info(const std::string &s, const int l)
:
card_name(s),
card_length(l)
{}

and then I think your code above is the equivalence of:

card_map["4"] = card_info("Visa",16);
card_map["4"] = card_info("Visa",13);

This ends up with card_map having one entry with

key == std::string("4") and value == card_info("Visa",13)


Is this what you want? If so, then why bother with the first insertion?

Did I misunderstand?

LR
 
N

news.aioe.org

brad said:
I might also note that this reference:

http://www.cppreference.com/cppmap/index.html

Indicates unique "key/value pairs". I was surprised to read that. It's
incorrect... if indeed we are talking about unique keys:

"C++ Maps are sorted associative containers that contain unique
key/value pairs."

Is there even a STL data structure that combines a key and value to form
uniqueness (no, "set" is not)?

Besides, the comparator should be a single parameter template class which
compares keys indicating that the uniqueness is maintained by the keys.
 
B

Brad

LR said:
and then I think your code above is the equivalence of:

card_map["4"] = card_info("Visa",16);
card_map["4"] = card_info("Visa",13);

This ends up with card_map having one entry with

key == std::string("4") and value == card_info("Visa",13)


Is this what you want? If so, then why bother with the first insertion?

Did I misunderstand?

I was initially using a map to store k, v pairs about credit cards. I
use the card prefix (4 in the case of visa) as the map key. Most card
prefixes are associated with *one* card length. To my knowledge, visa is
the only major card company with one prefix associated with multiple
card lengths (16 and 13). So credit card pre-validation software needs
to be able to handle this scenario. A map works fine until it is asked
to do this :)

Long story short, I switched to multimap and it now works as expected.
Thanks to all for the tips.
 
J

juanvicfer

cppreference.com is well known for containing
completely wrong statements like this. I'd
avoid the site entirely if I were you.

perhaps the adjective unique refers to key, not to key/value pairs.
it's the problem of ambiguous grammars.
 

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
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top