chen
chen

Reputation: 4510

map of vectors in STL?

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

Upvotes: 29

Views: 100453

Answers (9)

Loki Astari
Loki Astari

Reputation: 264729

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.

Upvotes: 7

VIPK
VIPK

Reputation: 9

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

Upvotes: -2

GutiMac
GutiMac

Reputation: 2472

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

Upvotes: 3

Kurt Krueckeberg
Kurt Krueckeberg

Reputation: 1245

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

Upvotes: 6

Kirill V. Lyadvinsky
Kirill V. Lyadvinsky

Reputation: 99715

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

Upvotes: 5

quamrana
quamrana

Reputation: 39414

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.

Upvotes: 6

fbrereto
fbrereto

Reputation: 35945

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

Upvotes: 33

UncleBens
UncleBens

Reputation: 41351

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.

Upvotes: 2

Steve Jessop
Steve Jessop

Reputation: 279445

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

Upvotes: 20

Related Questions