Home > Blockchain >  How to make a reference refer to another node of an std::unordered_map
How to make a reference refer to another node of an std::unordered_map

Time:07-15

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

  •  Tags:  
  • c
  • Related