I have an std::unordered_map<int, int>
which stores the frequency count of each element present in a given array. I need to find the max frequency element and print the key and frequency count.
#include <iostream>
#include <unordered_map>
#include <type_traits>
int main() {
std::unordered_map<int, int> mp {
{ 1, 2 },
{ 2, 54 },
{ 3, 32 },
{ 4, 8 },
{ 5, 56 },
{ 6, 23 },
{ 7, 9 },
{ 8, 87 },
{ 9, 69 },
};
auto maxP = std::ref(*mp.begin());
for (const auto& p : mp) {
if (p.second > maxP.get().second)
maxP = std::ref(std::add_lvalue_reference<std::pair<const int, int>&>(std::remove_const<const std::pair<const int, int>>(std::remove_reference<const std::pair<const int, int>&>(p))));
}
std::cout << maxP.get().first << ", " << maxP.get().second << std::endl;
}
But I'm getting the below error
<Main.cpp>:21:191: error: no matching function for call to 'std::remove_reference<const std::pair<const int, int>&>::remove_reference(const std::pair<const int, int>&)'
21 | maxP = std::ref(std::add_lvalue_reference<std::pair<const int, int>&>(std::remove_const<const std::pair<const int, int>>(std::remove_reference<const std::pair<const int, int>&>(p))));
|
CodePudding user response:
std::remove_reference
is not a callable. Its a type trait with a type
member alias. Same goes for std::add_lvalue_reference
. As you know all types, adding those type traits adds unnecessary complexity for no obvious gain. The code is barely readable, and frankly I don't understand how you expected it to work.
Anyhow you do not need any of this. The element is just a pair of int
s, so using a value rather than a reference wouldn't hurt too much. Using an iterator to the element rather than a reference would be much simpler as well. The easiest would be to use std::max_element
with a custom comparator:
#include <iostream>
#include <unordered_map>
#include <algorithm>
int main() {
std::unordered_map<int, int> mp {
{ 1, 2 },
{ 2, 54 },
{ 3, 32 },
{ 4, 8 },
{ 5, 56 },
{ 6, 23 },
{ 7, 9 },
{ 8, 87 },
{ 9, 69 },
};
auto it = std::max_element(mp.begin(),mp.end(),[](auto a,auto b) { return a.second < b.second;});
std::cout << it->first << ", " << it->second << std::endl;
}
For the question in the title
How to make a reference refer to another node of an std::unordered_map
Don't use a reference. Use an iterator. An iteration is already refering to an element. If you wanted to use a reference you'd use std::pair<const int,int>&
(of course you cannot rebind it, but you do not need that here).