boost::interprocess::map compiler error "cannot be overloaded" - c++
I am getting a compiler error trying to use boost::interprocess:map and I do not understand the error.
Declaring the map and its allocator
using namespace boost::interprocess;
struct Order {
uint64_t id = 0;
uint64_t val = 0;
};
typedef std::pair<const uint64_t, Order> ValueType;
typedef allocator<ValueType,
managed_shared_memory::segment_manager> OrderMapAllocator;
typedef map<const uint64_t,
Order,
std::less<const uint64_t>,
OrderMapAllocator> OrderMap;
Example usage, the compiler error points out line 120 which is the first line of the function below:
OrderMap * _orders;
void addOrder(Order order) {
if(_orders->find(order.id) != _orders->end()){
/* stuff */
} else {
(*_orders)[order.id] = order;
}
}
Note, I previously ran the code using std::map successfully, with the key non const instead of const. I switched the key to const uint64_t because a type assertion in boost was failing.
Gets the compiler errors below which I cannot interpret
For conciseness, the first one ends:
boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type = std::pair<const long unsigned int, Order>]’ cannot be overloaded
std::pair<iterator,bool> insert(const nonconst_value_type& x)
-
In file included from include/boost/interprocess/containers/map.hpp:23:0,
from src/app/SharedOrderBook.h:7,
from src/app/futures_feed.cpp:20:
include/boost/container/map.hpp: In instantiation of ‘class boost::container::map<const long unsigned int, Order, std::less<const long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >’:
src/app/SharedOrderBook.h:120:19: required from here
include/boost/container/map.hpp:541:29: error: ‘std::pair<typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator, bool> boost::container::map<Key, T, Compare, Allocator, Options>::insert(const nonconst_value_type&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type = std::pair<const long unsigned int, Order>]’ cannot be overloaded
std::pair<iterator,bool> insert(const nonconst_value_type& x)
^~~~~~
include/boost/container/map.hpp:530:29: error: with ‘std::pair<typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator, bool> boost::container::map<Key, T, Compare, Allocator, Options>::insert(const value_type&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::value_type = std::pair<const long unsigned int, Order>]’
std::pair<iterator,bool> insert(const value_type& x)
^~~~~~
include/boost/container/map.hpp:574:29: error: ‘std::pair<typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator, bool> boost::container::map<Key, T, Compare, Allocator, Options>::insert(boost::container::map<Key, T, Compare, Allocator, Options>::value_type&&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::value_type = std::pair<const long unsigned int, Order>]’ cannot be overloaded
std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
^~~~~~
include/boost/container/map.hpp:552:29: error: with ‘std::pair<typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator, bool> boost::container::map<Key, T, Compare, Allocator, Options>::insert(boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type&&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; typename boost::container::container_detail::tree<Key, std::pair<const Key, T>, boost::container::container_detail::select1st<std::pair<const Key, T> >, Compare, Allocator, MapOptions>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type = std::pair<const long unsigned int, Order>]’
std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x)
^~~~~~
include/boost/container/map.hpp:619:13: error: ‘boost::container::map<Key, T, Compare, Allocator, Options>::iterator boost::container::map<Key, T, Compare, Allocator, Options>::insert(boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator, const nonconst_value_type&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; boost::container::map<Key, T, Compare, Allocator, Options>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, true>; boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type = std::pair<const long unsigned int, Order>]’ cannot be overloaded
iterator insert(const_iterator p, const nonconst_value_type& x)
^~~~~~
include/boost/container/map.hpp:586:13: error: with ‘boost::container::map<Key, T, Compare, Allocator, Options>::iterator boost::container::map<Key, T, Compare, Allocator, Options>::insert(boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator, const value_type&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; boost::container::map<Key, T, Compare, Allocator, Options>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, true>; boost::container::map<Key, T, Compare, Allocator, Options>::value_type = std::pair<const long unsigned int, Order>]’
iterator insert(const_iterator p, const value_type& x)
^~~~~~
include/boost/container/map.hpp:628:13: error: ‘boost::container::map<Key, T, Compare, Allocator, Options>::iterator boost::container::map<Key, T, Compare, Allocator, Options>::insert(boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator, boost::container::map<Key, T, Compare, Allocator, Options>::value_type&&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; boost::container::map<Key, T, Compare, Allocator, Options>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, true>; boost::container::map<Key, T, Compare, Allocator, Options>::value_type = std::pair<const long unsigned int, Order>]’ cannot be overloaded
iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
^~~~~~
include/boost/container/map.hpp:598:13: error: with ‘boost::container::map<Key, T, Compare, Allocator, Options>::iterator boost::container::map<Key, T, Compare, Allocator, Options>::insert(boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator, boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type&&) [with Key = const long unsigned int; T = Order; Compare = std::less<const long unsigned int>; Allocator = boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; MapOptions = boost::container::tree_opt<(boost::container::tree_type_enum)0u, true>; boost::container::map<Key, T, Compare, Allocator, Options>::iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, false>; boost::container::map<Key, T, Compare, Allocator, Options>::const_iterator = boost::container::container_detail::iterator_from_iiterator<boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const long unsigned int, Order>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0u, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0u, boost::intrusive::dft_tag, 3u>, false>, true>; boost::container::map<Key, T, Compare, Allocator, Options>::nonconst_value_type = std::pair<const long unsigned int, Order>]’
iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
^~~~~~
In file included from include/boost/interprocess/segment_manager.hpp:33:0,
from include/boost/interprocess/detail/managed_memory_impl.hpp:30,
from include/boost/interprocess/managed_shared_memory.hpp:25,
from src/app/SharedOrderBook.h:6,
from src/app/futures_feed.cpp:20:
include/boost/interprocess/detail/named_proxy.hpp: In instantiation of ‘void boost::interprocess::ipcdetail::CtorArgN<T, is_iterator, Args>::construct(void*, boost::interprocess::ipcdetail::false_, const boost::container::container_detail::index_tuple<IdxPack ...>&) [with int ...IdxPack = {0, 1}; T = boost::container::map<const long unsigned int, Order, std::less<const long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >; bool is_iterator = false; Args = {std::less<long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0ul>, 0ul>, boost::interprocess::iset_index> >&}; boost::interprocess::ipcdetail::false_ = boost::interprocess::ipcdetail::bool_<false>]’:
include/boost/interprocess/detail/named_proxy.hpp:71:10: required from ‘void boost::interprocess::ipcdetail::CtorArgN<T, is_iterator, Args>::construct_n(void*, std::size_t, std::size_t&) [with T = boost::container::map<const long unsigned int, Order, std::less<const long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >; bool is_iterator = false; Args = {std::less<long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0ul>, 0ul>, boost::interprocess::iset_index> >&}; std::size_t = long unsigned int]’
src/app/futures_feed.cpp:170:1: required from here
include/boost/interprocess/detail/named_proxy.hpp:83:7: error: no matching function for call to ‘boost::container::map<const long unsigned int, Order, std::less<const long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >::map(std::less<long unsigned int>, boost::interprocess::allocator<std::pair<const long unsigned int, Order>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >&)’
{ ::new((void*)mem, boost_container_new_t())T(boost::forward<Args>(get<IdxPack>(args_))...); }
If I get rid of the const uint64_t and use uint64_t for the key, I get the error below:
include/boost/container/map.hpp:150:7: error: static assertion failed: (container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
Related
Boost interprocess unordered_map compilation
I'm using boost 1.53 and GCC 4.1.2. I've tried to use boost unordered_map in some tests (documentation says, that it should work with shared memory), but i'm unable to compile my code. With interprocess::map instead of unordered everything is ok. Typedefs: typedef boost::interprocess::allocator<char, SegmentManager> CharAllocator; typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> ShmString; typedef ShmString HashKeyType; //ComplexType is a wrapper for internal interprocess::map typedef ComplexType HashMappedType; typedef std::pair<const ShmString, ComplexType> HashValueType; typedef boost::interprocess::allocator<HashValueType, boost::interprocess::managed_shared_memory::segment_manager> HashMemAllocator; typedef boost::unordered_map < HashKeyType , HashMappedType , boost::hash<HashKeyType> ,std::equal_to<HashKeyType> , HashMemAllocator> TestHashMap; Allocation: boost::interprocess::managed_shared_memory segment( boost::interprocess::open_or_create, "MySharedMemory", 65536); thm_ = segment.construct<TestHashMap>("TestHashMap") (3, boost::hash<ShmString>(), std::equal_to<ShmString>() , segment.get_allocator<HashValueType>()); Usage: boost::interprocess::managed_shared_memory segment( boost::interprocess::open_only, "MySharedMemory"); ShmString str("123.345", segment.get_allocator<ShmString>()); ComplexType th("MySharedMemory"); HashValueType value(str, th); thm_->insert(value); And here is some error output: ../boost/include/boost/unordered/detail/allocate.hpp: In instantiation of 'boost::unordered::detail::allocator_traits<boost::interprocess::allocator<boost::unordered::detail::ptr_node<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >::pointer_to_other<const boost::unordered::detail::ptr_node<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> > >': ../boost/include/boost/unordered/detail/allocate.hpp:527: instantiated from 'boost::unordered::detail::allocator_traits<boost::interprocess::allocator<boost::unordered::detail::ptr_node<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >' ../boost/include/boost/unordered/detail/unique.hpp:114: instantiated from 'boost::unordered::detail::pick_node<boost::interprocess::allocator<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> >, std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >' ../boost/include/boost/unordered/detail/unique.hpp:158: instantiated from 'boost::unordered::detail::map<boost::interprocess::allocator<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> >, boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared, boost::hash<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > >, std::equal_to<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > > >' ../boost/include/boost/unordered/unordered_map.hpp:59: instantiated from 'boost::unordered::unordered_map<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared, boost::hash<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > >, std::equal_to<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > >, boost::interprocess::allocator<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >' utest/THUnitTests.cc:96: instantiated from here ../boost/include/boost/unordered/detail/allocate.hpp:523: error: ambiguous class template instantiation for 'struct boost::pointer_to_other<boost::interprocess::offset_ptr<boost::unordered::detail::ptr_node<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >, long int, long unsigned int, 0u>, const boost::unordered::detail::ptr_node<std::pair<const boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> > >' ../boost/include/boost/interprocess/offset_ptr.hpp:721: error: candidates are: struct boost::pointer_to_other<boost::interprocess::offset_ptr<T1, P1, O1, A1>, U> ../boost/include/boost/pointer_to_other.hpp:29: error: struct boost::pointer_to_other<Sp<T>, U> ../boost/include/boost/pointer_to_other.hpp:36: error: struct boost::pointer_to_other<Sp<T, T2>, U> ../boost/include/boost/pointer_to_other.hpp:43: error: struct boost::pointer_to_other<Sp<T, T2, T3>, U> I'm not sure if the problem is in my code, or because of old compiler version. If the problem is with compiler, then could it be fixed with newer version of boost? (i can't update my GCC). Or maybe there are some implementations of hash table, that are compatible with shared memory and with my compiler?
Here's a fixed up version. I just tried to make it self contained according to the suggestive comments. And it works. Hope it helps anyways: Live On Coliru #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/containers/string.hpp> #include <boost/interprocess/containers/map.hpp> #include <boost/unordered_map.hpp> namespace bip = boost::interprocess; // ShmString is boost::interprocess::basic_string typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> CharAllocator; typedef bip::basic_string<char, std::char_traits<char>, CharAllocator> ShmString; typedef ShmString HashKeyType; // ComplexType is a wrapper for internal interprocess::map struct ComplexType { typedef bip::allocator<std::pair<int const, int>, bip::managed_shared_memory::segment_manager> Alloc; typedef bip::map<int, int, std::less<int>, Alloc> Map; template <typename Alloc2> ComplexType(std::string, Alloc2 const& alloc = {}) : map(alloc) {} Map map; }; typedef ComplexType HashMappedType; typedef std::pair<const ShmString, ComplexType> HashValueType; typedef bip::allocator<HashValueType, bip::managed_shared_memory::segment_manager> HashMemAllocator; typedef boost::unordered_map<HashKeyType, HashMappedType, boost::hash<HashKeyType>, std::equal_to<HashKeyType>, HashMemAllocator> TestHashMap; int main() { // Allocation: { bip::managed_shared_memory segment(bip::open_or_create, "MySharedMemory", 65536); auto thm_ = segment.construct<TestHashMap>("TestHashMap")(3, boost::hash<ShmString>(), std::equal_to<ShmString>(), segment.get_allocator<HashValueType>()); } // Usage: bip::managed_shared_memory segment(bip::open_only, "MySharedMemory"); auto thm_ = segment.construct<TestHashMap>("TestHashMap")(3, boost::hash<ShmString>(), std::equal_to<ShmString>(), segment.get_allocator<HashValueType>()); ShmString str("123.345", segment.get_allocator<ShmString>()); ComplexType th("MySharedMemory", segment.get_segment_manager()); HashValueType value(str, th); thm_->insert(value); }
Custom allocator fails for std::map
I'm trying to use custom allocator with C++ STL containers, and it works with vector, but fails with map. Some strange error regarding mmap_allocator<std::_Rb_tree_node<std::pair<const int, int> > > and not using mmap_allocator<std::pair<const int, int> > as I was expecting In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/map:60, from 4.cpp:2: /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h: In member function ‘_Alloc std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::get_allocator() const [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’: /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:383: instantiated from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_destroy_node(std::_Rb_tree_node<_Val>*) [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’ /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:972: instantiated from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase(std::_Rb_tree_node<_Val>*) [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’ /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:614: instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::~_Rb_tree() [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’ /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_map.h:87: instantiated from here /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:354: error: no matching function for call to ‘mmap_allocator<std::pair<const int, int> >::mmap_allocator(const mmap_allocator<std::_Rb_tree_node<std::pair<const int, int> > >&)’ 4.cpp:37: note: candidates are: mmap_allocator<T>::mmap_allocator(const mmap_allocator<T>&) [with T = std::pair<const int, int>] 4.cpp:36: note: mmap_allocator<T>::mmap_allocator() [with T = std::pair<const int, int>] Here is the code: #include <vector> #include <map> #include <stdio.h> static size_t alloc; template <typename T> class mmap_allocator: public std::allocator<T> { public: typedef size_t size_type; typedef T* pointer; typedef const T* const_pointer; template<typename _Tp1> struct rebind { typedef mmap_allocator<_Tp1> other; }; pointer allocate(size_type n, const void *hint=0) { fprintf(stderr, "Alloc %d bytes.\n", n); alloc += n; return std::allocator<T>::allocate(n, hint); } void deallocate(pointer p, size_type n) { fprintf(stderr, "Dealloc %d bytes (%p).\n", n, p); alloc -= n; return std::allocator<T>::deallocate(p, n); } mmap_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); } mmap_allocator(const mmap_allocator &a) throw(): std::allocator<T>(a) { } ~mmap_allocator() throw() { } }; int main(){ std::vector<int, mmap_allocator<int> > int_vec(1024, 0, mmap_allocator<int>()); std::map<int, int, std::less<int>, mmap_allocator<std::pair<int,int> > > x; x[1] = 2; printf("s=%lu\n", alloc); return 0; } Linux, gcc 4.4.6.
I haven't tried fixing it but it seems you haven't defined a constructor which takes an allocator instantiation with a different template argument. That is, you are missing something like template <typename T> template <typename O> mmap_allocator<T>::mmap_allocator(mmap_allocator<O> const& other) { ... } From the looks of it, the error stems from trying to construct an allocator type obtained from rebind with some other allocator.
boost multi index container, class with pure virtual functions
I want to create multi_index_container with type A storing objects of type C, which is derived from B which is derived from A. Problem is that in A I have pure virtual function. When I try to compile it, I got errors which are described at the very bottom. I guess it's not possible to make-it-right? Is whole idea flawed? Code #include <iostream> #include <string> #include <boost/multi_index_container.hpp> #include <boost/multi_index/identity.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/mem_fun.hpp> using boost::multi_index_container; using namespace boost::multi_index; class A{ public: virtual void print()=0; std::string getName() const {return name;}; void setName(std::string s){name=s;}; std::string name; }; template<typename T> class B: public A{ public: virtual void print(){std::cout<<"B"<<name<<std::endl;} }; template<typename T> class C: public B<T> { public: virtual void print(){std::cout<<"C"<<reinterpret_cast<A*>(this)->name<<std::endl;} }; typedef multi_index_container< A, indexed_by< hashed_non_unique<const_mem_fun<A, std::string, &A::getName>> > > Container; int main(){ C<int> c; c.setName("c"); Container container; container.insert(c); return 0; } Errors In file included from /usr/local/include/boost/aligned_storage.hpp:20:0, from /usr/local/include/boost/type_traits/aligned_storage.hpp:11, from /usr/local/include/boost/multi_index/detail/index_node_base.hpp:17, from /usr/local/include/boost/multi_index/detail/node_type.hpp:23, from /usr/local/include/boost/multi_index/detail/index_base.hpp:21, from /usr/local/include/boost/multi_index/detail/base_type.hpp:21, from /usr/local/include/boost/multi_index_container.hpp:33, from wierdInheritance.cpp:13: /usr/local/include/boost/type_traits/alignment_of.hpp: In instantiation of ‘boost::detail::alignment_of_hack<A>’: /usr/local/include/boost/type_traits/alignment_of.hpp:71:5: instantiated from ‘const size_t boost::detail::alignment_of_impl<A>::value’ /usr/local/include/boost/type_traits/alignment_of.hpp:89:1: instantiated from ‘boost::alignment_of<A>’ /usr/local/include/boost/multi_index/detail/index_node_base.hpp:42:32: instantiated from ‘boost::multi_index::detail::pod_value_holder<A>’ /usr/local/include/boost/multi_index/detail/index_node_base.hpp:46:8: instantiated from ‘boost::multi_index::detail::index_node_base<A, std::allocator<A> >’ /usr/local/include/boost/multi_index/detail/hash_index_node.hpp:116:8: instantiated from ‘boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >’ /usr/local/include/boost/multi_index/hashed_index.hpp:108:54: instantiated from ‘boost::multi_index::detail::hashed_index<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName>, boost::hash<std::basic_string<char> >, std::equal_to<std::basic_string<char> >, boost::multi_index::detail::nth_layer<1, A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, std::allocator<A> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::hashed_non_unique_tag>’ /usr/local/include/boost/multi_index_container.hpp:70:7: instantiated from ‘boost::multi_index::multi_index_container<A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > > >’ wierdInheritance.cpp:57:19: instantiated from here /usr/local/include/boost/type_traits/alignment_of.hpp:42:7: error: cannot declare field ‘boost::detail::alignment_of_hack<A>::t’ to be of abstract type ‘A’ wierdInheritance.cpp:24:7: note: because the following virtual functions are pure within ‘A’: wierdInheritance.cpp:26:22: note: virtual void A::print() In file included from /usr/local/include/boost/multi_index_container.hpp:20:0, from wierdInheritance.cpp:13: /usr/local/include/boost/detail/allocator_utilities.hpp: In function ‘void boost::detail::allocator::construct(void*, const Type&) [with Type = A]’: /usr/local/include/boost/multi_index/detail/index_base.hpp:88:5: instantiated from ‘boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type* boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::insert_(boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type*) [with Value = A, IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, Allocator = std::allocator<A>, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type = boost::multi_index::detail::index_node_base<A, std::allocator<A> >, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type = const A&]’ /usr/local/include/boost/multi_index/hashed_index.hpp:701:63: instantiated from ‘boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::node_type* boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::insert_(boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::node_type*) [with KeyFromValue = boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName>, Hash = boost::hash<std::basic_string<char> >, Pred = std::equal_to<std::basic_string<char> >, SuperMeta = boost::multi_index::detail::nth_layer<1, A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, std::allocator<A> >, TagList = boost::mpl::vector0<mpl_::na>, Category = boost::multi_index::detail::hashed_non_unique_tag, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::node_type = boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >, typename SuperMeta::type::node_type = boost::multi_index::detail::index_node_base<A, std::allocator<A> >, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type = const A&]’ /usr/local/include/boost/multi_index_container.hpp:488:40: instantiated from ‘std::pair<typename boost::multi_index::detail::multi_index_base_type<Value, IndexSpecifierList, Allocator>::type::node_type*, bool> boost::multi_index::multi_index_container<Value, IndexSpecifierList, Allocator>::insert_(const Value&) [with Value = A, IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, Allocator = std::allocator<A>, typename boost::multi_index::detail::multi_index_base_type<Value, IndexSpecifierList, Allocator>::type::node_type = boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >]’ /usr/local/include/boost/multi_index/detail/index_base.hpp:150:30: instantiated from ‘std::pair<typename boost::multi_index::detail::multi_index_node_type<Value, IndexSpecifierList, Allocator>::type*, bool> boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::final_insert_(boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type) [with Value = A, IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, Allocator = std::allocator<A>, typename boost::multi_index::detail::multi_index_node_type<Value, IndexSpecifierList, Allocator>::type = boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type = const A&]’ /usr/local/include/boost/multi_index/hashed_index.hpp:254:61: instantiated from ‘std::pair<boost::multi_index::detail::hashed_index_iterator<boost::multi_index::detail::hashed_index_node<typename SuperMeta::type::node_type>, boost::multi_index::detail::bucket_array<typename SuperMeta::type::final_allocator_type> >, bool> boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::insert(boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type) [with KeyFromValue = boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName>, Hash = boost::hash<std::basic_string<char> >, Pred = std::equal_to<std::basic_string<char> >, SuperMeta = boost::multi_index::detail::nth_layer<1, A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, std::allocator<A> >, TagList = boost::mpl::vector0<mpl_::na>, Category = boost::multi_index::detail::hashed_non_unique_tag, typename SuperMeta::type::final_allocator_type = std::allocator<A>, typename SuperMeta::type::node_type = boost::multi_index::detail::index_node_base<A, std::allocator<A> >, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type = const A&]’ wierdInheritance.cpp:58:27: instantiated from here /usr/local/include/boost/detail/allocator_utilities.hpp:178:3: error: cannot allocate an object of abstract type ‘A’ wierdInheritance.cpp:24:7: note: since type ‘A’ has pure virtual functions
You cannot define a container of A, but you can define a container of pointers (eg. shared_ptr) to A: typedef multi_index_container< A *, indexed_by< hashed_non_unique<const_mem_fun<A, std::string, &A::getName>> > > Container; or: typedef multi_index_container< boost::shared_ptr<A>, indexed_by< hashed_non_unique<const_mem_fun<A, std::string, &A::getName>> > > Container;
boost interprocess map with int and string
I have the following code that saves a map into shared memory using boost interprocess using namespace boost::interprocess; //Shared memory front-end that is able to construct objects //associated with a c-string. Erase previous shared memory with the name //to be used and create the memory segment at the specified address and initialize resources shared_memory_object::remove("MySharedMemory"); try{ managed_shared_memory segment (create_only ,"MySharedMemory" //segment name ,655360); //segment size in bytes //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>, //so the allocator must allocate that pair. typedef allocator<char, managed_shared_memory::segment_manager> CharAllocator; typedef basic_string<char, std::char_traits<char> ,CharAllocator> MyShmString; typedef allocator<MyShmString, managed_shared_memory::segment_manager> StringAllocator; typedef int KeyType; typedef std::pair<const int, StringAllocator> ValueType; typedef StringAllocator MappedType; typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator; typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap; //Initialize the shared memory STL-compatible allocator ShmemAllocator alloc_inst (segment.get_segment_manager()); CharAllocator charallocator (segment.get_segment_manager()); //Construct a shared memory map. //Note that the first parameter is the comparison function, //and the second one the allocator. //This the same signature as std::map's constructor taking an allocator MyMap *mymap = segment.construct<MyMap>("MyMap") //object name (std::less<int>() //first ctor parameter ,alloc_inst); //second ctor parameter //Insert data in the map MyShmString mystring(charallocator); mystring = "this is my text"; for(int i = 0; i < 100; ++i){ //mymap[i] = mystring; mymap->insert(std::pair<const int, MappedType>(i, mystring)); } } this code doesnt compile.. it throws the following error no matching function for call to ‘std::pair<const int, boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >::pair(int&, main()::MyShmString&)’ /usr/include/c++/4.2.1/bits/stl_pair.h:84: note: candidates are: std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const int, _T2 = boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >] /usr/include/c++/4.2.1/bits/stl_pair.h:80: note: std::pair<_T1, _T2>::pair() [with _T1 = const int, _T2 = boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >] /usr/include/c++/4.2.1/bits/stl_pair.h:69: note: std::pair<const int, boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >::pair(const std::pair<const int, boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, 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 difference if ::pair(int&, main()::MyShmString&) so i am guessing mymap->insert(std::pair<const int, MappedType>(i, mystring)); is not the correct way to go.. so how should i insert into the map, if the error is there.. else what is the error?
Surely the value_type is: typedef std::pair<const int, MyShmString > ValueType; not typedef std::pair<const int, StringAllocator> ValueType; And similarly: typedef MyShmString MappedType; not typedef StringAllocator MappedType;
Your types are different, is that intentional? MyShmString is not the same as MappedType - may be you ought to change the following line: typedef StringAllocator MappedType; to typedef MyShmString MappedType;
C++: Help Creating unordered_map with User-Defined Hash/Equality
I'm trying to create a std::unordered_map, using a user-defined hash function and equality predicate, for matrix rows of integral built-in types. I use std::bind, since I need the hashing and equality functors to work for variable ranges. How would I get the following code to compile and work as intended? I'm guessing that my mistake is towards the bottom of the listing, where I use std::bind and instantiate the std::unordered_map. Some clarifications: I can't use boost::hash_combine because I care about individual bits in the integers stored in the matrix row, so unless I create my own iterator, boost::hash_combine would combine whole integers, leading to erroneous results. Also, I need the hash and equality functors to work on ranges from 1 to ~200,000, so specifying the range in template parameters would not be a reasonable option. template <class T,class F,class A> struct row_hash_right : std::function<size_t( ublas::matrix_row<ublas::matrix<T,F,A>>, unsigned, unsigned)> { typedef ublas::matrix_row<ublas::matrix<T,F,A>> row_type; // I want to use std::bind to bind the last two arguments. size_t operator()(row_type& a, unsigned s, unsigned e) { // Implementation of hash function. } }; template <class T,class F,class A> struct row_equal_right : std::function<bool( ublas::matrix_row<ublas::matrix<T,F,A>>, ublas::matrix_row<ublas::matrix<T,F,A>>, unsigned, unsigned)> { typedef ublas::matrix_row<ublas::matrix<T,F,A>> row_type; bool operator()(row_type& a, row_type& b, unsigned s, unsigned e) { // Implementation of equality predicate. } }; // Inside a function. for (unsigned i = 0; i < len; ++i) { for (unsigned j = i + 1; j < len; ++j) { auto x = std::bind(r_hash, _1, i, j); auto y = std::bind(r_equal, _1, _2, i, j); // ERROR: std::unordered_map<row_type, unsigned, decltype(x), decltype(y)> m(256, x, y); } } The error: Here is (what I think) the most important part of the error produced upon attempted compilation: /usr/include/c++/4.6/bits/stl_pair.h:92:11: error: ‘std::pair<_T1, _T2>::first’ has incomplete type /usr/include/boost/numeric/ublas/fwd.hpp:73:11: error: declaration of ‘const struct boost::numeric::ublas::matrix_row, boost::numeric::ublas::unbounded_array > > >’ If you want the see the whole thing, I've dumped it all here: In file included from /usr/include/c++/4.6/bits/stl_algobase.h:65:0, from /usr/include/c++/4.6/bits/char_traits.h:41, from /usr/include/c++/4.6/ios:41, from /usr/include/c++/4.6/ostream:40, from /usr/include/c++/4.6/iostream:40, from src/test/read_test.cpp:1: /usr/include/c++/4.6/bits/stl_pair.h: In instantiation of ‘std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>’: /usr/include/c++/4.6/bits/stl_function.h:486:12: instantiated from ‘std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >’ /usr/include/c++/4.6/bits/hashtable_policy.h:789:20: instantiated from ‘std::__detail::_Hash_code_base, boost::numeric::ublas::unbounded_array > > >, std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>, std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>’ /usr/include/c++/4.6/bits/hashtable.h:105:11: instantiated from ‘std::_Hashtable, boost::numeric::ublas::unbounded_array > > >, std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>’ /usr/include/c++/4.6/bits/unordered_map.h:44:11: instantiated from ‘std::__unordered_map, boost::numeric::ublas::unbounded_array > > >, unsigned int, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, false>’ /usr/include/c++/4.6/bits/unordered_map.h:256:11: instantiated from ‘std::unordered_map, boost::numeric::ublas::unbounded_array > > >, unsigned int, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> > >’ ./sal/alg/ehh.hpp:144:31: instantiated from ‘sal::ehh_results sal::compute_ehh(boost::numeric::ublas::matrix&, unsigned int) [with FloatType = double, T = unsigned int, F = boost::numeric::ublas::basic_row_major, A = boost::numeric::ublas::unbounded_array >]’ src/test/read_test.cpp:11:51: instantiated from here /usr/include/c++/4.6/bits/stl_pair.h:92:11: error: ‘std::pair::first’ has incomplete type /usr/include/boost/numeric/ublas/fwd.hpp:73:11: error: declaration of ‘const struct boost::numeric::ublas::matrix_row, boost::numeric::ublas::unbounded_array > > >’
If you want to hash a range of things, you need something like hash_combine(). I usually lift this function from Boost (surprisingly, it wasn't included in the standard!). Here's how I'd use it on std::arrays, and I trust you can manipulate this into something to work on matrix rows: #include <array> template <class T> inline void hash_combine(std::size_t & seed, const T & v) { std::hash<T> hasher; seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } namespace std { template<typename T, size_t N> struct hash<array<T, N>> { inline size_t operator()(const array<T, N> & a) const { size_t seed = 0; for (size_t i = 0; i != N; ++i) { ::hash_combine(seed, a[i]); } return seed; } }; } (The above specialisation allows you to use std::unordered_set<std::array<int, 10>> etc.) If the matrix rows don't come with an equality predicate, you could also add a specialization of std::equal_to for matrix rows.