unexpected copies with foreach over a map

Viewed 1800

I am trying to loop over the entries of a map, and I get unexpected copies. Here is the program:

#include <iostream>
#include <map>
#include <string>

struct X
{
    X()
    {
        std::cout << "default constructor\n";
    }

    X(const X&)
    {
        std::cout << "copy constructor\n";
    }
};

int main()
{
    std::map<int, X> numbers = {{1, X()}, {2, X()}, {3, X()}};
    std::cout << "STARTING LOOP\n";
    for (const std::pair<int, X>& p : numbers)
    {
    }
    std::cout << "ENDING LOOP\n";
}

And here is the output:

default constructor
copy constructor
default constructor
copy constructor
default constructor
copy constructor
copy constructor
copy constructor
copy constructor
STARTING LOOP
copy constructor
copy constructor
copy constructor
ENDING LOOP

Why do I get three copies inside the loop? The copies disappear if I use type inference:

for (auto&& p : numbers)
{
}

What's going on here?

3 Answers
Related