0

I'm new to C++ and trying to understand a simple example of inserting a list of integers into a map.

#include <iostream>
#include <map>
#include <list>
using namespace std;

map<string, list<int>> m;

void insert(list<int>& list_to_insert)
{
    m.insert({"ABC", list_to_insert});
}

void setup()
{
    std::list<int> local_list = { 7, 5, 16, 8 };
    insert(local_list);
}

int main()
{
    setup();
    cout << m["ABC"].size(); // PRINTS 4
}

As far as my understanding, local_list is a variable only known to the setup function. When I pass in a reference to the insert function, I expect it to work. However, at the end of setup, I expect local_list to be removed from the stack frame. However, in my main function, when I call size(), I see that it has in fact persisted throughout. I am not sure I understand how local_list gets persisted at the end of setup(). What is exactly happening here?

  • By default, C++ works with copies/values, not references. If you are coming from another language such as Java, then I can understand your confusion. – PaulMcKenzie Nov 08 '21 at 15:38

1 Answers1

2
map<string, list<int>> m;

contains lists, not references to lists. So your

m.insert({"ABC", list_to_insert});

will create a copy of the passed list.

PS: why-is-using-namespace-std-considered-bad-practice

Stefan Riedel
  • 796
  • 4
  • 15
  • Ah that explains it. Is this the general idiom to create a map: to invoke copying the key/value? Or perhaps using pointers to objects that you are interested in inserting? – vipman12 Nov 08 '21 at 15:39
  • @vipman12 • All of the above. They are all valid options, and have their use cases. Which one to use depends on the situation. – Eljay Nov 08 '21 at 15:42
  • That depends on what you're trying to achieve. If you want to store "references" to some big or expensive-to-copy objects, then use pointers (because you can't use actual references here). If not, use copies. – Stefan Riedel Nov 08 '21 at 15:43
  • @StefanRiedel Or if you want to avoid copies, then one could create the big objects inside the map directly. Or, if that is not an option and the big object elsewhere won't be needed anymore and is cheap to move, then move instead of copying. – eerorika Nov 08 '21 at 15:45
  • @eerorika that's right. If you're going to have those objects just in the map (which might be the best approach depending on the situation), then `.emplace(...)` them right into the map. – Stefan Riedel Nov 08 '21 at 15:48
  • Compilers are pretty smart these days. Id the compiler can tell you're copying a variable that will go out of scope without being used again, it's likely the compiler will optimize out the copy. See [the As If Rule](https://en.cppreference.com/w/cpp/language/as_if). Can you count on this? A profiler will tell you if you need to worry. – user4581301 Nov 08 '21 at 16:02