0

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)))); | 
1
  • As a general rule, when you're trying to manipulate the language to get around something like constness, that's usually a sign you're doing something sketchy. As another general rule, you should prioritize clean, readable code over anything else. If you have a performance issue with that, you should prove it before trying to optimize it. Commented Jul 14, 2022 at 11:35

1 Answer 1

1

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 ints, 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).

Sign up to request clarification or add additional context in comments.

3 Comments

just now I got this idea, instead of std::ref I should use std::cref while initializing auto maxP = std::cref(*mp.begin());.
@Harry why do you want to use std::ref?
@Harry std::ref is a workaround to let you store references in containers. Thats its use case. Here you do not need it. You could use a pointer, would be much simpler

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.