mushi mushi - 3 years ago 209
C++ Question

Interesting use-case where a regular array cannot stand-in for a std::array

This comes across as an interesting use-case of a std::array over a regular array: somewhere where I cannot change the syntax to work for a regular array (or so I have convinced myself).

#include <iostream>
#include <algorithm>
#include <array>
#include <map>

using namespace std;

int main()
{
int n, c = 0; cin >> n;
array<int, 3> tri;
map<array<int, 3>, int> freq;

while (n--)
{
cin >> tri[0] >> tri[1] >> tri[2];
sort(begin(tri), end(tri));
freq[tri]++;
}

for (auto i : freq)
{
cout << &i.first << ' ' << i.second << endl;
if (i.second == 1)
{
c++;
}
}

cout << c;
}


When I try to switch the std::array over with a regular
int[3]
, and the map template parameters to
map<int*, int>
, the program seems to make the map
freq
reuse
tri
, even if I put it inside the while loop, as if an optimization.

Note that for working with
map<int*, int>
the statement for printing the map's contents would be

cout << i.first << ' ' << i.second << endl;


My question is, why isn't the std::array experiencing technical difficulties here? What is the hidden magic underneath the
freq[tri]++
statement?

Here's where I found the code.

Answer Source

The reason std::array does not have an issue here is because it does not decay to a pointer unlike a raw array. So, when you use std::array you get a copy of it in the map which is unique to the map. When you use a raw array you get a pointer to that array and you would have to dynamically allocate them to get different arrays since you copy the pointer, not the array into the map.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download