std::multimap

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

std::multimap

Postby Lena » Tue Oct 17, 2017 4:22 am

Hi.
I would like to have a container multimap would store the key multiple values, such as:
key=String
int value1
int value2
Code: Select all
std::multimap<String, std::vector<int> > IniContent;
//***
String FullName = item->Data[L"FullName"].AsString();
std::vector<int> &values = IniContent[FullName]; //error here
//***

[bccaarm Error] UnitDibocca.cpp(59): type 'std::multimap<String, std::vector<int> >' does not provide a subscript operator
How correct?
C++ Builder Berlin.
Last edited by Lena on Tue Oct 17, 2017 6:17 am, edited 2 times in total.
Lena
BCBJ Master
BCBJ Master
 
Posts: 526
Joined: Sun Feb 06, 2011 1:28 pm

Re: std::multimap

Postby Lena » Tue Oct 17, 2017 5:12 am

And an additional question
If I do not need automatic sorting (in multimap), which container should I use?
Code: Select all
std::vector<std::pair<String, std::pair<int,int>> > MyPair;
//***
String FullName = item->Data[L"FullName"].AsString();
std::vector<std::pair<int,int>> &values = MyPair[FullName];//error
//***

[bccaarm Error] UnitDibocca.cpp(64): no viable overloaded operator[] for type 'std::vector<std::pair<String, std::pair<int, int> > >'
Lena
BCBJ Master
BCBJ Master
 
Posts: 526
Joined: Sun Feb 06, 2011 1:28 pm

Re: std::multimap

Postby rlebeau » Tue Oct 17, 2017 6:07 pm

Lena wrote:[bccaarm Error] UnitDibocca.cpp(59): type 'std::multimap<String, std::vector<int> >' does not provide a subscript operator


The error is correct. std::multimap does not have a subscript operator.

Lena wrote:How correct?


You should be using std::map instead:

Code: Select all
std::map<String, std::vector<int>> IniContent;


std::multimap allows multiple entries to have the same key value, which is why a subscript operator is not provided (you have to use std::multimap::equal_range() to find all entries that match a given key value). That is not what you want. std::map holds entries with unique keys, and thus provides a subscript operator to access entries by key value.

Also, on a side note, since you are using a C++11 compiler, you should consider using 'auto' to help clean up your variable declarations when the compiler can deduce their types for you:

Code: Select all
std::map<String, std::vector<int>> IniContent;
...
auto &values = IniContent[FullName]; // <-- here


Lena wrote:If I do not need automatic sorting (in multimap), which container should I use?


Have a look at std::unordered_map:

Code: Select all
std::unordered_map<String, std::vector<int>> IniContent;


Lena wrote:
Code: Select all
std::vector<std::pair<String, std::pair<int,int>> > MyPair;
//***
String FullName = item->Data[L"FullName"].AsString();
std::vector<std::pair<int,int>> &values = MyPair[FullName];//error
//***

[bccaarm Error] UnitDibocca.cpp(64): no viable overloaded operator[] for type 'std::vector<std::pair<String, std::pair<int, int> > >'


Correct, because the subscript operator of std::vector takes an array index, not a key value. If you want to use a vector of pairs, you will have to use the std::find_if() algorithm to find a given pair by its key value:

Code: Select all
using MyPair = std::pair<String, std::vector<int>>;
std::vector<MyPair> IniContent;
...
String FullName = item->Data[L"FullName"].AsString();
auto iter = std::find_if(IniContent.begin(), IniContent.end(),
                         [=](const MyPair &pair){ return (pair.first == FullName); });
if (iter == IniContent.end())
{
    IniContent.emplace_back(FullName, std::vector<int>());
    iter = IniContent.end() - 1;
}
auto &values = iter->second;
// use values as needed...
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: std::multimap

Postby Lena » Wed Oct 18, 2017 3:28 am

Thank you very much for the detailed explanation!

For example I need a container allows multiple entries to have the same key value and not need automatic sorting.
Is the simplest way use std::find_if() ?
and definition
Code: Select all
using MyPair = std::pair<String, std::vector<int>>;
std::vector<MyPair> IniContent;
//***
Lena
BCBJ Master
BCBJ Master
 
Posts: 526
Joined: Sun Feb 06, 2011 1:28 pm

Re: std::multimap

Postby rlebeau » Wed Oct 18, 2017 10:12 am

Lena wrote:For example I need a container allows multiple entries to have the same key value and not need automatic sorting.


Why, though? You are keying off of a person's name. Are you expecting multiple users to have the same name? When searching for a name, how do you expect to differentiate between different people of the same name? If you just search for the name by itself, you will always find one and only one person, but you won't know if it is the right person, especially in an unordered container where ANY user may be the first one found.

What are you REALLY trying to accomplish?
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: std::multimap

Postby Lena » Wed Oct 18, 2017 11:39 am

What are you REALLY trying to accomplish?


This menu is for a restaurant. For example, two identical names for a salad. In one of the salads there is salt, but not in the other. Salad names can be the same.
Lena
BCBJ Master
BCBJ Master
 
Posts: 526
Joined: Sun Feb 06, 2011 1:28 pm

Re: std::multimap

Postby rlebeau » Wed Oct 18, 2017 2:28 pm

Lena wrote:This menu is for a restaurant. For example, two identical names for a salad. In one of the salads there is salt, but not in the other. Salad names can be the same.


Doesn't it make more sense to name them differently instead? For instance, "Salad - Salted" and "Salad - Unsalted", or "Salad w/ Salt" and "Salad w/o Salt". If you give them the exact same name, and you key off of the names, you are just making things harder for yourself. Personally, I would not identify items by name to begin with. It makes more sense to track the items by unique ID numbers instead, then you can give multiple items different IDs but the same name for display purposes.
Last edited by rlebeau on Thu Oct 19, 2017 9:33 am, edited 1 time in total.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: std::multimap

Postby Lena » Thu Oct 19, 2017 5:39 am

You are absolutely right. According to your recommendations, I convinced the owner of the restaurant that all dishes should have a different name. Thank you for your recommendations. Your recommendations convinced the owner of the restaurant!
Your support is the best! Thank You for this forum!
Lena
BCBJ Master
BCBJ Master
 
Posts: 526
Joined: Sun Feb 06, 2011 1:28 pm


Return to Technical

Who is online

Users browsing this forum: No registered users and 15 guests

cron