1

I am trying to insert a values into the boost map but the call to the insert statement is ambiguous in boost map insert.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <functional>
#include <utility>

using namespace boost::interprocess;

    int main ()
    {

    // remove earlier existing SHM
    shared_memory_object::remove("SharedMemoryName");

    // create new
    managed_shared_memory segment(create_only,"SharedMemoryName",65536);

    //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
    //so the allocator must allocate that pair.
    typedef std::string KeyType;
    typedef map<std::string, int>  MappedType;
    typedef std::pair<const KeyType, MappedType> ValueType;

    //allocator of for the map.
    typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;


    //Initialize the shared memory STL-compatible allocator
    ShmemAllocator alloc_inst (segment.get_segment_manager());

    //third parameter argument is the ordering function is used to compare the keys.
    typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MySHMMap;

    //offset ptr within SHM for map
    offset_ptr<MySHMMap> m_pmap = segment.construct<MySHMMap>("MySHMMapName")(std::less<std::string>(), alloc_inst);

    //Insert data in the map
           std::string my_string = "test";
            m_pmap[0].insert(std::make_pair( my_string, 0) );


    return 0;
}

The boost APIs that get called are:

    std::pair<iterator,bool> insert(const nonconst_value_type& x)
    std::pair<iterator,bool> insert(const value_type& x)
    typedef typename tree_t::value_type             value_type;
    typedef std::pair<key_type, mapped_type>        nonconst_value_type;

Error Log:

/home/user/droy/src/quotes/shmmutimap/src/writer.cxx:39: error:  call of overloaded 'insert(std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>)' is ambiguous
/home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/interprocess/containers/container/map.hpp:410: note: candidates are: std::pair<typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::iterator, bool> boost::container::map<Key, T, Pred, Alloc>::insert(const typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::value_type&) [with Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, T = boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, Pred = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Alloc = boost::interprocess::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >]
/home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/interprocess/containers/container/map.hpp:421: note:                 std::pair<typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::iterator, bool> boost::container::map<Key, T, Pred, Alloc>::insert(const std::pair<typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::key_type, T>&) [with Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, T = boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, Pred = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Alloc = boost::interprocess::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >]

The parameters to the insert statement end up to be the same type,how could I get around this problem, any hints?

deb
  • 631
  • 1
  • 5
  • 15
  • When asking about compiler errors, **always quote the exact compiler error in it's entirety** along with indication which line gives it. Also include the surrounding compiler output, it often contains "notes" that further explain the error. – Jan Hudec Oct 16 '14 at 16:46
  • I have updated the code and the error logs as per your suggestions.Thanks! – deb Oct 16 '14 at 17:33
  • Posted the #include and namespace. – deb Oct 16 '14 at 19:37

1 Answers1

1

Right now, you create a map<string, map<string, int>>. I imagine that your intention was to create just a map<string, int>. To do that, you need a very simple fix to your code:

// typedef map<std::string, int>  MappedType;
typedef int MappedType;

As an aside, you could also write the last line of your code as:

// m_pmap[0].insert(std::make_pair( my_string, 0) );
m_pmap[0][my_string] = 0;

Updates:

As it appears that my intuition was wrong, and you did want to create a map<string, map<string, int>>, then the response is slightly different.

Note that your call is basically attempting to do this:

map<string, int> x(0);
m_pmap[0][my_string] = x;

Note that there is no constructor for map<string, int> that takes an integer. Instead, you could do any of:

m_pmap[0].insert(std::make_pair( my_string, map<std::string, int>()));
m_pmap[0].insert(std::make_pair( my_string, MappedType()));
m_pmap[0][my_string] = map<std::string, int>();
m_pmap[0][my_string] = MappedType();

You could also simply take advantage of how the map works, and do:

m_pmap[0]["us"]["abc"] = 2030;
m_pmap[0]["us"]["def"] = 1230;
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • Hi Bill thank you for your inputs, however my intention was to create a map>, I will tell you why I am doing this, I have a country codes, for each country code we have symbols, time that I want to keep track of. I am posting an example below. US- ABC-20:30, DEF-12:30, Australia - UFG-23:20, XGF-16:30 and later on I would want to do some calculation on the time part.Thanks! – deb Oct 16 '14 at 20:23
  • There has to be a workaround to call a specific kind of overloaded operator I think, I am not sure though how I will do that. I came across this post http://stackoverflow.com/questions/9622149/boostbind-and-insert-of-a-boostunordered-map but was not able to apply to my situation. Thanks. – deb Oct 16 '14 at 20:32