29

I am stuck on trying to figure out how to insert a vector for a value in a map. For example:

#include <iostream> #include <vector> #include <map> using namespace std; int main() { map <int, vector<int> > mymap; mymap.insert(pair<int, vector<int> > (10, #put something here#)); return 0; } 

I don't know what syntax to use insert a vector for value. I tried {1,2}, but that failed. What syntax should I use?

Everything works if I declare a vector in advance and give it a name, but I don't want to do that, as I want to have a map with a lot of vectors.

Thank You in Advance

1
  • How do you know what the contents should be? Commented May 7, 2012 at 19:30

6 Answers 6

31

If you want an empty vector you could do:

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

You could then add whatever elements you want with something like:

mymap[10].push_back(1); mymap[10].push_back(2); 

Edit: Removed incorrect assertion that the vectors would be copied if/when the map grows. As the commenters pointed out, this is not true for std::map, which is node-based.

Sign up to request clarification or add additional context in comments.

2 Comments

maps store by value yes, but growing the map will never ever copy the key/value pair. Period. Ever. So just put the vector in it. Same with list, set, multimap, and multiset. They're called "node based containers" because of this property.
Your answer is wrong starting at But, which is quite a lot. Growing a map does not imply moving its content. Ever. One of the unfortunate (1) requirements of map is that once set an element will not move until it is erased. (1) Unfortunate because it was derived from a known implementation rather than thought out from first principles (on the role of the container) and precludes more efficient implementations than red-black trees, such as B-trees.
12

Basically your question is not about inserting std::vector into a std::map. Your question is how can you easily create an anonymous std::vector with arbitrary initial element values.

In ISO C++03, you can't. C++11 allows using initialization lists for this, however.

If you are stuck with a C++03 compiler, you possibly could create a helper function to return a vector with specified elements:

std::vector<int> make_vector(int a, int b) { std::vector<int> v; v.push_back(a); v.push_back(b); return v; } 

If the vectors you're inserting are of different sizes, you could use a variadic function, although doing so would require that you either pass along the number of elements or have a reserved sentinel value.

1 Comment

You can make an anonymous vector, just not with values. Just get it by reference after you made it and add them in after construction. The helper function is indeed the best way though in C++03.
11

If you are using C++11 you can use vector's initialization list constructor (the last constructor in that list) which would look like this:

mymap.insert(pair<int, vector<int> > (10, {1, 2, 3})); 

If you can only use C++03, vector has a constructor that takes a size and a default value for each element that might be enough for you. Otherwise you will have to construct the vector and then insert it. If you want to avoid an unnessicary copy of the vector when inserting you could swap it in like so:

vector<int> myvec; myvec.push_back(1); myvec.push_back(2); mymap[10].swap(myvec); 

This way the vector won't need to be copied. You'll get an extra vector default construction but that's not very expensive.

Comments

4

#put something here# = vector<int>{1,2}

I'm surprised though that {1,2} didn't work. Are you not using a C++11 compiler? If not then you can only create the vector with default constructor there (no values), or fill it with values first and stick it in.

3 Comments

vector also has a constructor that will create a new vector with n copies of the same initial value.
my compiler is Code::Blocks 10.05, and your suggestions doesn't work for me. I am guessing that it can't be done with my compiler.
@Akavall, that's your IDE. It uses some old version of GCC with the download link, so you have to manually upgrade the compiler and libraries.
1

This should work in C++2003 compilers.

#include <iostream> #include <vector> #include <map> #include <cassert> using namespace std; std::vector<int> make_vector(int a, int b) { std::vector<int> result; result.push_back(a); result.push_back(b); return result; } int main() { map <int, vector<int> > mymap; mymap.insert(make_pair(10, make_vector(1,2))); // Or, alternatively: // mymap[10] = make_vector(1,2); assert(mymap[10][0] == 1); assert(mymap[10][1] == 2); return 0; } 

Comments

1

C++03 does not have initializer lists, which can be a pain to initialize collections.

If you cannot upgrade to a more modern version of the compiler, you can always use the Boost.Assignment library. It has a list_of function precisely for this.

#put something here# -> boost::assign::list_of(1)(2) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.