Home » C++ » map of vectors in STL?

map of vectors in STL?

Posted by: admin January 4, 2018 Leave a comment

Questions:

I want to have a map of vectors, (but I don’t want to use pointer for the internal vector), is it possible?

// define my map of vector
map<int, vector<MyClass> > map;

// insert an empty vector for key 10. # Compile Error
map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>)); 

I know that if I have used pointer for vector, as follows, it would be fine, but I wonder if I can avoid using pointer and use the above data structure (I don’t want to manually delete)

// define my map of vector
map<int, vector<MyClass>* > map;

// insert an empty vector for key 10.
map.insert(pair<int, vector<MyClass>* >(10, new vector<MyClass>)); 
Answers:

The first data structure will work. You might want to typedef some of the code to make future work easier:

typedef std::vector<MyClass>      MyClassSet;
typedef std::map<int, MyClassSet> MyClassSetMap;

MyClassSetMap map;
map.insert(MyClassSetMap::value_type(10, MyClassSet()));

or (thanks quamrana):

map[10] = MyClassSet();

Questions:
Answers:

Yes, but your second line should be:

map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>()));

This inserts a pair consisting of the integer 10, and an empty vector. Both will be copied, and if you’re dealing with large vectors then you’ll want to be careful about copies.

Also: don’t call variables “map” while using namespace std. You’re scaring me 😉

Questions:
Answers:

Using the typedefs from fbrereton you can also do this:

typedef std::vector<MyClass>      MyClassSet;
typedef std::map<int, MyClassSet> MyClassSetMap;

MyClassSetMap map;
map[10]=MyClassSet();

You can use operator[] instead of insert(). This saves on the line noise a bit.

Questions:
Answers:

Use the swap function to efficiently add your vector.

map<int, vector<SomeClass> > Map;

vector<SomeClass> vec;
//...add elements to vec

Map[1] = vector<int>();
// swap the empty vector just inserted with your vector.
Map[1].swap(vec); 

Questions:
Answers:

You should read compile error messages. They usually gives you all information that you need.
Your code gives error 'illegal use of this type as an expression' in that string. That means that you use type, not an object. To use an object you could just add () for calling constructor with no arguments.

map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>()));

By the way you could use std::make_pair to create pairs. It deduces argument types, so no need to explicitly indicate them.

map.insert( make_pair( 10, vector<MyClass>() ) );

Questions:
Answers:

You could use the [] operators.
These will insert the value into the map.

map[10]; // create the 10 element if it does not exist
         // using the default constructor.

If you are going to use soon after construction then:

std::vector<MyClass>&  v = map[10];

Now its constructed and you have a local reference to the object.

Questions:
Answers:

You are just missing a pair of parenthesis:

map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>()));

Incidentally, there’s a helper function std::make_pair which takes care of deducing the template arguments:

map.insert(make_pair(10, vector<MyClass>()));

Considering using a pointer to dynamically allocated vector instead is a rather bad idea, since this will make you responsible for managing the instance. Also, since map should never move its contents around in memory, there is nothing to gain performance-wise neither.

Questions:
Answers:

Lets use a little bit c++11 😉

typedef std::vector<MyClass>      MyClassSet;
typedef std::map<int, MyClassSet> MyClassSetMap;

MyClassSetMap map;
map.emplace(myid, MyClassSet());

To know if this was inserted you can do:

const auto result = map.emplace(myid, MyClassSet());
return (result.second) 
? "Is_OK"
: "Maybe "+myid+" exists\n"; 

And here is the flagship of c++11 and maps…. how to insert in this map a pair if it doesn’t exists and if it exists just insert a new element in the vector….

const auto result = map.emplace(myid, MyClassSet());
result.first->second.emplace(objSet);

I hope give a useful information!!!