C++, How to create a map with key and value as structs in C++? (2024)

C++, How to create a map with key and value as structs in C++? (1)Author: Howard JohnsonDate: 2022-07-05

Question:I have a mapand my structure is defined as follows.in myMap key is int and value is vector of structure Is it possible to have a map where the key is a string, and the value is an array of structures?

  • How to create a map with key and value as structs in C++?
  • How can I make a map where the value is an array of structs in C++
  • How to create the map Of the vector of structure in c++
  • C++: struct pointer in map structure
  • What is map () in C?
  • How do you create a structure in C?
  • Is there a map in C?
  • What is the structure of a map in C++?

How to create a map with key and value as structs in C++?

Question:

I'm trying to create a map whose key and value are both structs (stE and stR), so I have something like this:

 struct stR{ char* est; char* et; };struct stE{ int num; char* form; char* et; map<stE,stR> s; }; 

But when I want to insert a new element:

stE e;e.num=1;e.form="a";e.et="b";stE f;f.num=2;f.form="c";f.et="d";stR r;r.est="e";r.et="";e.s.insert(make_pair(f, r));

It gives me an error:

C:\Dev-Cpp\include\c++\3.4.2\bits\stl_function.h In member function `bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = stEstado]':

I can't find what's the problem. Could anyone help me?Thanks in advance.


Solution 1:

When using a map, you need to provide a less-than operator or give it a comparer since it orders the keys automatically.

bool stE::operator< (const stE &);

Solution 2:

You need to provide strict weak ordering comparison, which you can achieve by definingoperator<for yourstEor passing a comparator function of functor as a map template parameter.std::maplooks something like this:

template<class Key, class T, class Compare = std::less<Key>, ... > class map;

By default,Compareis set to useT::operator<(const T&), but you can pass your own functor type which implements the logic. This is important if you cannot modify the actual class.

Bear in mind that the map needs to be able to insert default constructedstRobjects, and your current structure has no default constructor, to the pointers will be initialized to random values. This could be an issue further along the line.

Also, your key struct has a map where it is it's own key type. This could cause recursion problems when you try to implement the less-than comparison:

struct stE{ int num; char* form; char* et; map<stE,stR> s; // how do we use this in the comparison?}; 

Hash Table in C/C++ - A Complete Implementation, A good Hash function to map keys to values; A Hash Table Data Structure that supports insert, search and delete operations. A Data Structure to

Map in C++ with practical examples

An important characteristic of the map collection is that it orders elements by key in ascendingDuration: 19:52

How can I make a map where the value is an array of structs in C++

Question:

I have the following structure.

struct Tourist { string name; string surname; string sex;};

I would like to sort tourists by families.

int getMinRoomsAmount(Tourist touristsList[]) { map<string, Tourist[]> families; for (int i=0; i < 40; i++) { families[touristsList[i].surname] = // to append the array with the tourist } return 0;}

Is it possible to have a map where the key is a string, and the value is an array of structures?And how can I append the array with new entries?


Solution 1:

  • Map :You could use a map of string and vector of Tourist -map<string, std::vector<Tourist> > families;.
  • Insertion :For adding a new element to a family, just usepush_back()method of vector as -families[touristsList[i].surname].push_back(touristsList[i]);. This statement will simply add the family(Touriststruct) to the map with key of surname.

Below is a working demo of your program -

#include <iostream>#include<map>#include<vector>struct Tourist { std::string name; std::string surname; std::string sex;};int getMinRoomsAmount(std::vector<Tourist> touristsList) { std::map<std::string, std::vector<Tourist> > families; for (int i=0; i < 3; i++) { // to append the array with the tourist families[touristsList[i].surname].push_back(touristsList[i]); } // iterating over the map and printing the Tourists families-wise for(auto it:families){ std::cout<<"Family "<<it.first<<" : \n"; for(auto family : it.second){ std::cout<<family.name<<" "<<family.surname<<" "<<family.sex<<std::endl; } std::cout<<"\n-------\n"; } return 0;}int main() { // making 3 struct objects just for demo purpose Tourist t1={"a1","b1","m"}; Tourist t2={"a2","b1","f"}; Tourist t3={"a3","b3","m"}; // inserting the objects into vector and then passing it to the function std::vector<Tourist>t={t1,t2,t3}; getMinRoomsAmount(t);}

I have just included 3 Tourist objects for demo purpose. You can modify the code to suit your needs. I have used vectors instead of array because they are more efficient and you can dynamically push/pop as per the user inputs later on if you want to modify the program.

Hope this helps !

Solution 2:

You really want to stay away from arrays, especially when usingstd::map. Thestd::mapwill copy your structure and arrays don't copy well.

Here is the definition of a map with value as an std::vector:

std::map<std::string, std::vector<Tourist>> 

Here is how to add to the map:

std::vector<Tourist> database;Tourist t1{"x", "x", "x"};Tourist t2{"y", "y", "y"};Tourist t3{"z", "z", "z"};database.pushback(t1);database.pushback(t2);database.pushback(t3);// Check this out:std::map<std::string, std::vector<Tourist>> visitors;visitor["Italy"] = database;

Solution 3:

Use a map of string→vector<Tourist>.

Then use the vectors in the normal way, e.g.push_back.

Map in C++ Standard Template Library (STL), Maps are associative containers that store elements in a mapped fashion. Each element has a key value and a mapped value.

How to create the map Of the vector of structure in c++

Question:

I have a mapstd::map<int, std::vector<Data>>myMapand my structure is defined as follows.

 struct Data { int x; int z; int y; };

in myMap key is int and value is vector of structure and I dont want create the temporary vector or structure while inserting to the map. Is there any idea to achieve it?


Solution 1:

One method is to useemplaceandstd::move

myMap.emplace(key, std::move(myVec));

By usingstd::moveyou can construct the vector outside of the map, and then move that vector into the map without any copying.

Solution 2:

You don't need to explicitly initilize values in a map. When you access a key viaoperator[]that does not exist in the map it will be added with a default initialized value (an emptystd::vectorin your case).

So you can safely do something like

myMap[0].push_back(myInstanceOfData)

even if the key 0 does not exist. Then it will be created along with an empty vector as value and the valuemyInstanceOfDatawill be pushed to this new vector inside the map.

Solution 3:

As the previous answer said, you can use emplace and std::move, but to test if it or any other solution works, I suggest you override the constructor, copy constructor, destructor, and the assignment operator to print something like created, copied, destroyed, assigned respectively, so you know what's actually going on, and improve performance.

Map in C++ with practical examples, An important characteristic of the map collection is that it orders elements by key in ascendingDuration: 19:52

C++: struct pointer in map structure

Question:

I declared a struct like this, and the following data structures

struct piece{ int start, height, end; piece(int a, int b, int c){ start = a; height = b; end = c; }};vector<piece> piecesTog;map <int,piece*> data;

Then, when I read the elements I do this:

while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){ piecesTog.push_back( piece(aux1, aux2, aux3) ); data[a] = data[c] = &piecesTog[tam];}

Well, until now, I have had no problem.However, later in the program, I have to use the piece* part, to do so, I use an iterator like this

 for(map< int, piecesTog* >::iterator it = data.begin(); it != data.end(); it++){ piece* aux = it->second; ... }

I want to have access to the structure that the it->second points, but I tried everything and nothing worked.

I printed the memory adress of it->second and &piecesTog[tam] and they are the same, but when I do (*aux).height or it->second->height they give number completely crazy, probably some trash.

I have no clue why that is happening.

If anyone has any idea how to fix it, I would appreciate it.


Solution:

while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){ piecesTog.push_back( piece(aux1, aux2, aux3) ); data[a] = data[c] = &piecesTog[tam];}

is almost certainly not following the Iterator invalidation rules.

piecesTog.push_back( piece(aux1, aux2, aux3) );

can trigger a resize which typically creates a new datastore, copies the elements from the old data store to the new one and then deletes the old datastore, leaving the pointers cached by

data[a] = data[c] = &piecesTog[tam];

dangling. When you use those pointers some time in the future, Ka-Blammo! Undefined Behaviour and an easily identified crash if you're lucky.

Insufficient information has been provided to supply a definitive solution, but here are a few general alternatives (in order of attractiveness):

If you know ahead of time the number ofpieces that will go intopiecesTog, you canreservestorage to eliminate the need to resize thevector.

If elements are only added to the end of thevectorand no elements are ever removed, you can store the indexes of the elements rather than pointers to them. If the ordering never changes, the indexes will always refer to the correct elements no matter how many more items are added.

If it is possible to do so, rewrite the reader to load all of thepiecesintopiecesTogand then build the maps.

The above options all assume thatpiecesTogis assembled all at once and then left alone. If your insertion is more free-form, you sort the structure or you remove elements, you'll need to use a data structure with more favourable invalidation rules such asstd::list.

Map or Structure in C, This tutorial will discuss using the map or structure to create a collection of variables in C. Map or Structure in C.

Related posts:

Search by value in a Map in C++C++11 search an std::map with composite keyHow to insert value in c++ map std::map<string , list<string> in c++?Push_back() vs emplace_back() in C++ STL VectorsInitialize 1000 map elementsPush_back vs emplace_backCreating a vector of custom type objectsC++ Vector Library - pop_back() FunctionHow to add to std::map an object with constant field?Copy std::map data to another mapCould not print map of map value in C++How to ensure that a std::map is ordered?How can I create multiple objects with for loop in C++?Is there a way to start vector indexing from 1 in c++?Is there a way to remove a key from a C++ map without deleting the contents?Store struct in a map; Checking if a struct exist inside a mapInitializing a std::map when the size is known in advanceHow to get the size of a c++ class member vector?How to store Data Triplet in a Vector in C++?Comparing unordered_map vs unordered_setAny similar function like JS Array.prototype.map in c++?Generating a vector with int and string argumentsC++ How to insert a new element in a sorted vector?How to push_back() C array into std::vector [duplicate]How to initialise memory with new operator in C++?Advantages of using arrays instead of std::vector?How to use map::end from map::find in C++C++ Vector vs Array Initial capacity of vector in C++Most efficient way of initializing a map of vectors in C++

Write a comment:

C++, How to create a map with key and value as structs in C++? (2024)
Top Articles
Latest Posts
Article information

Author: Ms. Lucile Johns

Last Updated:

Views: 6652

Rating: 4 / 5 (61 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Ms. Lucile Johns

Birthday: 1999-11-16

Address: Suite 237 56046 Walsh Coves, West Enid, VT 46557

Phone: +59115435987187

Job: Education Supervisor

Hobby: Genealogy, Stone skipping, Skydiving, Nordic skating, Couponing, Coloring, Gardening

Introduction: My name is Ms. Lucile Johns, I am a successful, friendly, friendly, homely, adventurous, handsome, delightful person who loves writing and wants to share my knowledge and understanding with you.