3

I'm having trouble inserting a reference to an object into a map in C++.

Here is some sample code to show what I want to do:

#include <iostream>
#include <map>

class Foo {
public:
    // ...

    void addToMap();
};

std::map<std::string, Foo&> myMap;

void Foo::addToMap() {
    myMap.insert(std::make_pair(std::string("hello"), *this));
}

int main() {
    Foo foo;
    foo.addToMap();
}

When I compile, I get a very cryptic error message of

main.cpp: In member function ‘void Foo::addToMap()’:
main.cpp:12:48: error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, Foo&>::insert(std::pair<const char*, Foo>)’
     myMap.insert(std::make_pair("hello", *this));
                                                ^
In file included from /usr/include/c++/6.3.1/map:61:0,
                 from main.cpp:2:
/usr/include/c++/6.3.1/bits/stl_map.h:731:7: note: candidate: std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = Foo&; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::__cxx11::basic_string<char>, Foo&>]
       insert(const value_type& __x)
       ^~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:731:7: note:   no known conversion for argument 1 from ‘std::pair<const char*, Foo>’ to ‘const value_type& {aka const std::pair<const std::__cxx11::basic_string<char>, Foo&>&}’
/usr/include/c++/6.3.1/bits/stl_map.h:739:9: note: candidate: template<class _Pair, class> std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(_Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = std::__cxx11::basic_string<char>; _Tp = Foo&; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >]
         insert(_Pair&& __x)
         ^~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:739:9: note:   template argument deduction/substitution failed:
/usr/include/c++/6.3.1/bits/stl_map.h:735:32: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
       template<typename _Pair, typename = typename
                                ^~~~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:752:7: note: candidate: void std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::initializer_list<std::pair<const _Key, _Tp> >) [with _Key = std::__cxx11::basic_string<char>; _Tp = Foo&; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >]
       insert(std::initializer_list<value_type> __list)
       ^~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:752:7: note:   no known conversion for argument 1 from ‘std::pair<const char*, Foo>’ to ‘std::initializer_list<std::pair<const std::__cxx11::basic_string<char>, Foo&> >’
/usr/include/c++/6.3.1/bits/stl_map.h:781:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = Foo&; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::__cxx11::basic_string<char>, Foo&>]
       insert(const_iterator __position, const value_type& __x)
       ^~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:781:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/6.3.1/bits/stl_map.h:792:9: note: candidate: template<class _Pair, class> std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, _Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = std::__cxx11::basic_string<char>; _Tp = Foo&; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >]
         insert(const_iterator __position, _Pair&& __x)
         ^~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:792:9: note:   template argument deduction/substitution failed:
main.cpp:12:48: note:   candidate expects 2 arguments, 1 provided
     myMap.insert(std::make_pair("hello", *this));
                                                ^
In file included from /usr/include/c++/6.3.1/map:61:0,
                 from main.cpp:2:
/usr/include/c++/6.3.1/bits/stl_map.h:807:9: note: candidate: template<class _InputIterator> void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = std::__cxx11::basic_string<char>; _Tp = Foo&; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, Foo&> >]
         insert(_InputIterator __first, _InputIterator __last)
         ^~~~~~
/usr/include/c++/6.3.1/bits/stl_map.h:807:9: note:   template argument deduction/substitution failed:
main.cpp:12:48: note:   candidate expects 2 arguments, 1 provided
     myMap.insert(std::make_pair("hello", *this));

I have no idea how to make the pointer this into a reference, which I can then insert into the map. How would I go about fixing the code?

1
  • I would think that std::map<std::string, Foo&> myMap; Should be std::map<std::string, Foo*> myMap; The & just "converts" a datatype to an address Commented Mar 29, 2017 at 20:03

1 Answer 1

2

The standard library containers can't contain references. Use pointers instead, or wrap your references to T in std::reference_wrapper<T> instead, e.g.

#include <functional>
#include <map>
#include <string>

std::map<std::string, std::reference_wrapper<Foo> > myMap;
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.