15

When we use a complicated container in C++, like

std::vector<std::map<std::string, std::set<std::string>>> table;

The only way to add an empty map (which may represent a row or column) is to initialize a new element and push it back. For example with

table.push_back(std::map<std::string, std::set<std::string>>());

Is there any way to avoid redeclaring the type, and just adding the correct typed element?

Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
Vineet
  • 346
  • 6
  • 18

4 Answers4

34

From CLion's IntelliSense, I later found that one useful method is emplace_back(). This constructs a new object of correct type and adds it to the end of the vector.

table.emplace_back();
Vineet
  • 346
  • 6
  • 18
25

You can take advantage of copy-list-initialization (since C++11) and just write

table.push_back({});
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
11

Before C++11 sometimes I use x.resize(x.size()+1), in C++11 or later you can use x.push_back({}).

6502
  • 112,025
  • 15
  • 165
  • 265
5

Though the other answers are correct, I will add that if you couldn't take that approach, you could have benefitted from declaring some type aliases to shorten that container type name.

I can of course only guess at the logical meaning of your containers, which is another thing that this fixes!

 using PhilosopherNameType = std::string;
 using NeighboursType      = std::set<PhilosopherNameType>;
 using NeighbourMapType    = std::map<PhilosopherNameType, NeighboursType>;

 std::vector<NeighbourMapType> table;
 table.push_back(NeighbourMapType());

I mention this because you can likely still benefit from this in other places.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055