1

I would like to write a function to returning reference of iterator of an map entry in order to update the value of the entry. However, it fails at compile stage

#include <map>
#include <iostream>

using namespace std;

pair<int, string>& map_find(map<int,string>& m, int k){
    return *(m.find(k));
}

int main()
{
    map<int,string> m;
    
    // insert an entry
    m.insert(make_pair<int,string>(128490,"def"));
    
    // search entry by key
    auto e = map_find(m,128490);
    
    cout << e.first << e.second<<endl;;

    e.second = "abc"; // Update value
    
    // verify if the entry is updated
    e = map_find(m,128490);
    
    cout << e.first << e.second<<endl;;

    return 0;
}
main.cpp: In function ‘std::pair<int, std::__cxx11::basic_string<char> >& map_find(std::map<int, std::__cxx11::basic_string<char> >&, int)’:
main.cpp:15:12: error: invalid initialization of reference of type ‘std::pair >&’ from expression of type ‘std::pair >’
     return *(m.find(k));
            ^~~~~~~~~~~~

2 Answers 2

5

The value type of std::map<Key, Value> is std::pair<const Key, Value>, not std::pair<Key, Value>. There are also useful member type aliases.

#include <map>
#include <iostream>

using MyMap = std::map<int, std::string>;

MyMap::reference map_find(MyMap& m, int k){
    return *(m.find(k));
}

int main()
{
    MyMap m;
    
    m.emplace(128490,"def");
    
    auto e = map_find(m,128490);
    
    std::cout << e.first << e.second << std::endl;

    // Does not update the string in the map, because e is a copy.   
    e.second = "abc";
    
    e = map_find(m,128490);
    
    std::cout << e.first << e.second << std::endl;

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

In the class template std::map the value type is declared like

typedef pair<const Key, T> value_type;

As you can see the first template parameter has the qualifier const. And iterators of the class template return references to object of value_type.

So you need to write at least like

pair<const int, string>& map_find(map<int,string>& m, int k){
    return *m.find(k);
}

Otherwise you could change the key that would result in undefined behavior.

Pay attention to that the function is unsafe if the element with the given key is not found because in this case there will be an attempt to dereference the iterator that does not point to.an actual element.

Also instead of this statement

auto e = map_find(m,128490);

you need to write

auto &e = map_find(m,128490);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.