28
votes

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>)); 
9

9 Answers

31
votes

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();
19
votes

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 ;-)

6
votes

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.

6
votes

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); 
6
votes

You could use the [] operator.

It 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 the value soon after construction then:

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

Now it's constructed and you have a local reference to the object.

4
votes

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>() ) );
3
votes

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!!!

2
votes

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.

-2
votes
// define my map of vector
map<int, vector<MyClass> > map;
MyClass *ptr = new MyClass();
map[0].push_back(ptr);

pushing objects into vector of type MyClass

//usage; map[0][vector_index]
map[0][0]->MyClassMember;

accessing member functions using vector_index