30

In Python, I can write a map literal like this:

mymap = {"one" : 1, "two" : 2, "three" : 3}

How can I do the equivalent in C++11?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
abw333
  • 5,571
  • 12
  • 41
  • 48

2 Answers2

56

You can actually do this:

std::map<std::string, int> mymap = {{"one", 1}, {"two", 2}, {"three", 3}};

What is actually happening here is that std::map stores an std::pair of the key value types, in this case std::pair<const std::string,int>. This is only possible because of c++11's new uniform initialization syntax which in this case calls a constructor overload of std::pair<const std::string,int>. In this case std::map has a constructor with an std::intializer_list which is responsible for the outside braces.

So unlike python's any class you create can use this syntax to initialize itself as long as you create a constructor that takes an initializer list (or uniform initialization syntax is applicable)

aaronman
  • 18,343
  • 7
  • 63
  • 78
  • Actually `std::pair`. But they take the same sorts of initializers. – aschepler Nov 26 '13 at 23:32
  • @aschepler good point fixed it, I guess the key is always given a const qualifier – aaronman Nov 26 '13 at 23:33
  • I don't think that's accurate. `{"one",1}` is uniform initialization (potentially even _aggregate initialization_ if std::pair is actually POD). Only the outer `{}` is an initializer list. It still _works_ because of uniform initialization (otherwise `mymap({ {a,b}, {c,d} })` would have been required) – sehe Nov 26 '13 at 23:36
  • @sehe it's still valid to refer to it as an initializer list, but I'll edit the answer to make it clearer – aaronman Nov 26 '13 at 23:37
  • 1
    @aaronman Actually it isn't. In fact, overload resolution is very specific in the presence of initializer lists so the distinction is quite good to make (signatures taking an initializer list are always preferred for uniform initialization; uniform initialization does ***not*** imply an initializer list) – sehe Nov 26 '13 at 23:42
  • @sehe what would refer to the `{...}` used in uniform initialization then – aaronman Nov 26 '13 at 23:45
  • Your answer is still not accurate. As @sehe mentions, when using uniform initialization, a constructor taking initializer lists is always preferred, and if that is not available/non-viable, then other constructors are attempted for matches. Since `pair` is not an aggregate, and doesn't have a constructor that accepts an initializer list, it's that last part that makes the above expression work. – Praetorian Nov 26 '13 at 23:46
  • @aaronman You would refer to that as... _uniform initialization_. And you could add that it invokes a constructor overload. (Yeah, it's a shame. Uniform initialization isn't really that uniform :() – sehe Nov 26 '13 at 23:47
  • @Praetorian which part specifically is wrong, I'm a little confused – aaronman Nov 26 '13 at 23:49
  • @aaronman This part *either uniform initialization, a call to a constructor that takes an initializer list or aggregate initialization*. It's none of those, it actually matches `std::pair`'s constructor that takes two arguments (for each of the contained types) – Praetorian Nov 26 '13 at 23:51
  • @Praetorian so when you match to a constructor are using .... – aaronman Nov 26 '13 at 23:54
  • @aaronman I don't know of a succinct phrase to refer to it, it's just plain old construction that has been enabled by the new uniform initialization syntax. – Praetorian Nov 27 '13 at 00:15
  • @Praetorian I think the lack of terminology for this syntax has been confusing me – aaronman Nov 27 '13 at 00:19
27

You may do this:

std::map<std::string, int> mymap = {{"one", 1}, {"two", 2}, {"three", 3}};
abw333
  • 5,571
  • 12
  • 41
  • 48
  • 16
    I couldn't find the answer on SO, so I added it to save other programmers some time. SO actually encourages this: http://stackoverflow.com/help/self-answer – abw333 Nov 26 '13 at 23:25
  • @abw333 arguably that's not for trivia "look-it-up" reference style questions... Just imagine "How do I add two numbers in Jquery" (interestingly: [Adding numbers in Jquery](http://stackoverflow.com/questions/16117985/adding-numbers-in-jquery) :) – sehe Nov 26 '13 at 23:27
  • 4
    @sehe I'm just trying to help. I spent a few minutes Googling for this and had no success and eventually had to ask someone to figure out the answer. I didn't see it on SO, so I posted this so that the answer could be more easily found. – abw333 Nov 26 '13 at 23:33
  • 5
    You shouldn't share your personal opinion on language x vs language y in SO. This syntax is fine because unlike Python, `std::map` isn't a built-in type in the core language and it's statically typed rather than dynamically typed. It's like comparing apples to cars. – Rapptz Nov 26 '13 at 23:34
  • @Rapptz You're right. I edited my response. – abw333 Nov 26 '13 at 23:36