I am trying to use heterogeneous lookup with boost::unordered_map so I can look things up without constructing a string in shared memory, and I'm running into an issue with the interprocess allocators. It works with the standard allocator and I can't find anything online about this
#include <string_view>
#include <string>
#include <boost/unordered_map.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
namespace intprocss = boost::interprocess;
using Segment = intprocss::managed_shared_memory;
using SegmentManager = Segment::segment_manager;
using Allocator = intprocss::allocator<void, SegmentManager>;
typedef intprocss::managed_shared_memory::segment_manager segment_manager_t;
typedef intprocss::allocator<char, segment_manager_t> CharAllocator;
typedef intprocss::basic_string<char, std::char_traits<char>, CharAllocator> shared_string;
using SharedStringPair = std::pair<const shared_string, shared_string>;
using SharedStringPairAllocator = intprocss::allocator<SharedStringPair, SegmentManager>;
struct string_hash
{
using hash_type = std::hash<std::string_view>;
using is_transparent = void;
std::size_t operator()(shared_string const& str) const { return hash_type{}(str); }
std::size_t operator()(std::string_view str) const { return hash_type{}(str); }
std::size_t operator()(std::string const& str) const { return hash_type{}(str); }
};
int main()
{
boost::unordered_map<shared_string, int, string_hash, std::equal_to<>, SharedStringPairAllocator> myMap;
return 0;
}
and the errors are
In file included from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/implementation.hpp:49,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/map.hpp:7,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/unordered_map.hpp:23,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered_map.hpp:17,
from <source>:3:
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/fca.hpp: In instantiation of 'boost::unordered::detail::grouped_bucket_array<Bucket, Allocator, SizePolicy>::grouped_bucket_array() [with Bucket = boost::unordered::detail::bucket<boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >, boost::interprocess::offset_ptr<void> >; Allocator = 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::iset_index> > >, int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; SizePolicy = boost::unordered::detail::prime_fmod_size<>]':
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/implementation.hpp:2071:26: required from 'boost::unordered::detail::table<Types>::table() [with Types = 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::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::iset_index> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, 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::iset_index> > >, int, string_hash, std::equal_to<void> >]'
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/unordered_map.hpp:1867:49: required from 'boost::unordered::unordered_map<K, T, H, P, A>::unordered_map() [with K = 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::iset_index> > >; T = int; H = string_hash; P = std::equal_to<void>; A = 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::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::iset_index> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
<source>:32:104: required from here
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/fca.hpp:507:33: error: no matching function for call to 'boost::interprocess::allocator<boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::allocator()'
507 | empty_init_t(), node_allocator_type()),
| ^~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/segment_manager.hpp:38,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/detail/managed_memory_impl.hpp:30,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/managed_shared_memory.hpp:25,
from <source>:4:
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:142:4: note: candidate: 'template<class T2> boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T2, SegmentManager>&) [with T = boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
142 | allocator(const allocator<T2, SegmentManager> &other)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:142:4: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/fca.hpp:507:33: note: candidate expects 1 argument, 0 provided
507 | empty_init_t(), node_allocator_type()),
| ^~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:136:4: note: candidate: 'boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T, SegmentManager>&) [with T = boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
136 | allocator(const allocator &other)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:136:4: note: candidate expects 1 argument, 0 provided
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:131:4: note: candidate: 'boost::interprocess::allocator<T, SegmentManager>::allocator(segment_manager*) [with T = boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>; segment_manager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
131 | allocator(segment_manager *segment_mngr)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:131:4: note: candidate expects 1 argument, 0 provided
ASM generation compiler returned: 1
In file included from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/implementation.hpp:49,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/map.hpp:7,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/unordered_map.hpp:23,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/unordered_map.hpp:17,
from <source>:3:
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/fca.hpp: In instantiation of 'boost::unordered::detail::grouped_bucket_array<Bucket, Allocator, SizePolicy>::grouped_bucket_array() [with Bucket = boost::unordered::detail::bucket<boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >, boost::interprocess::offset_ptr<void> >; Allocator = 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::iset_index> > >, int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; SizePolicy = boost::unordered::detail::prime_fmod_size<>]':
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/implementation.hpp:2071:26: required from 'boost::unordered::detail::table<Types>::table() [with Types = 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::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::iset_index> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, 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::iset_index> > >, int, string_hash, std::equal_to<void> >]'
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/unordered_map.hpp:1867:49: required from 'boost::unordered::unordered_map<K, T, H, P, A>::unordered_map() [with K = 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::iset_index> > >; T = int; H = string_hash; P = std::equal_to<void>; A = 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::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::iset_index> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
<source>:32:104: required from here
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/fca.hpp:507:33: error: no matching function for call to 'boost::interprocess::allocator<boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::allocator()'
507 | empty_init_t(), node_allocator_type()),
| ^~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/segment_manager.hpp:38,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/detail/managed_memory_impl.hpp:30,
from /opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/managed_shared_memory.hpp:25,
from <source>:4:
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:142:4: note: candidate: 'template<class T2> boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T2, SegmentManager>&) [with T = boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
142 | allocator(const allocator<T2, SegmentManager> &other)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:142:4: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_82_0/boost/unordered/detail/fca.hpp:507:33: note: candidate expects 1 argument, 0 provided
507 | empty_init_t(), node_allocator_type()),
| ^~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:136:4: note: candidate: 'boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T, SegmentManager>&) [with T = boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
136 | allocator(const allocator &other)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:136:4: note: candidate expects 1 argument, 0 provided
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:131:4: note: candidate: 'boost::interprocess::allocator<T, SegmentManager>::allocator(segment_manager*) [with T = boost::unordered::detail::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::iset_index> > >, int>, boost::interprocess::offset_ptr<void> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>; segment_manager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
131 | allocator(segment_manager *segment_mngr)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_82_0/boost/interprocess/allocators/allocator.hpp:131:4: note: candidate expects 1 argument, 0 provided
Execution build compiler returned: 1