tags:

views:

572

answers:

6

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>));
+7  A: 

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();
fbrereto
+6  A: 

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

Steve Jessop
It's even easier to write `map.insert( std::make_pair( 10, vector<MyClass>() ) );`
xtofl
thanks! this website is really awesome!
chen
@xtofl: yes, I meant "should" in the sense of "to get rid of the compiler error". fbrereton also makes good points about making the code more concise.
Steve Jessop
+1 for pointed out "using map with std namespace" :)Scared me too
Fu4ny
why not use the type inside map. map::value_type!
Martin York
@xtofl. Its even easier to use the [] operator. (see below)
Martin York
+2  A: 

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.

UncleBens
+2  A: 

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.

quamrana
touché!
fbrereto
I think you meant map[10] = MyClassSet(); Actually it should also be possible to write just map[10]; (to add a small element of surprise).
UncleBens
@UncleBens - Oops, yup, I'll fix it!
quamrana
This depends upon how this is called. Insert may be faster if you know there will be no conflicts.
mLewisLogic
+3  A: 

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>() ) );
Kirill V. Lyadvinsky
+1 for suggestion to read compiler errors. However, they are compiler-specific. With GCC the error is "expected primary-expression before ...", which IMO has a generic meaning of "something's wrong here" - you just need to take a good look at the code to figure it out. (Trying to compile with different compilers might be a good idea, I've had error messages that are not only unclear but misleading, e.g "second parameter is wrong" where the error was in the first parameter.)
UncleBens
+1  A: 

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.

Martin York