Ускорить ошибки компиляции межпроцессного оператора flat_map []

Я создаю обертку над boost::interprocess::flat_map, проблема в том, что по какой-то причине я не могу использовать operator[] или at. Когда я использую find или insert, он успешно компилируется.

typedef boost::interprocess::managed_shared_memory::segment_manager SegmentManager;
typedef boost::interprocess::allocator<char, SegmentManager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>,
        CharAllocator> ShmString;
typedef short KeyType;
typedef ShmString MappedType;
typedef std::pair<const short, ShmString> ValueType;

typedef boost::interprocess::allocator<ValueType,
        boost::interprocess::managed_shared_memory::segment_manager> ShMemAlloc;
typedef boost::interprocess::flat_map<KeyType, MappedType,
        std::less<short>, ShMemAlloc> ShMap;


class Wrapper {

public:

    Wrapper(boost::interprocess::managed_shared_memory* memSeg) :
            m_memSeg(memSeg) {
        const ShMemAlloc initAlloc(m_memSeg->get_segment_manager());
        m_storage = m_memSeg->construct
            <ShMap> (boost::interprocess::anonymous_instance)
            (std::less<KeyType>(), initAlloc);
        ShmString str(initAlloc);
        ValueType val(10, str);

        m_storage->insert(val); //Ok

        ShMap::iterator it = m_storage->find(5); //Ok
        if(it != m_storage->end())
            it->second = str;

        (*m_storage)[5] = str; //Compilation error
    };
    ~Wrapper();

protected:
    boost::interprocess::managed_shared_memory* m_memSeg;

    ShMap* m_storage;
};

Кажется, есть проблема с выводом типа в аллокаторе внутри вызова operator[], но я понятия не имею, как это правильно использовать.

Вот отчет об ошибке:

../boost/include/boost/container/string.hpp: In instantiation of 'boost::container::container_detail::basic_string_base<Allocator>::members_holder::members_holder() [with Allocator = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]':
../boost/include/boost/container/string.hpp:104:18:   required from 'boost::container::container_detail::basic_string_base<Allocator>::basic_string_base() [with Allocator = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
../boost/include/boost/container/string.hpp:596:16:   required from 'boost::container::basic_string<CharT, Traits, Allocator>::basic_string() [with CharT = char; Traits = std::char_traits<char>; Allocator = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
../boost/include/boost/container/detail/value_init.hpp:31:13:   required from 'boost::container::container_detail::value_init<T>::value_init() [with T = 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/include/boost/container/flat_map.hpp:846:52:   required from 'boost::container::flat_map<Key, T, Compare, Allocator>::mapped_type& boost::container::flat_map<Key, T, Compare, Allocator>::priv_subscript(const key_type&) [with Key = short int; T = 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> > >; Compare = std::less<short int>; Allocator = boost::interprocess::allocator<std::pair<const short int, 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::flat_map<Key, T, Compare, Allocator>::mapped_type = 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::flat_map<Key, T, Compare, Allocator>::key_type = short int]'
../boost/include/boost/container/flat_map.hpp:469:4:   required from 'typename boost::enable_if_c<(((! boost::is_class<BOOST_MOVE_TEMPL_PARAM>::value) || (! boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value)) && (! boost::is_same<Key, BOOST_MOVE_TEMPL_PARAM>::value)), T&>::type boost::container::flat_map<Key, T, Compare, Allocator>::operator[](const BOOST_MOVE_TEMPL_PARAM&) [with BOOST_MOVE_TEMPL_PARAM = int; Key = short int; T = 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> > >; Compare = std::less<short int>; Allocator = boost::interprocess::allocator<std::pair<const short int, 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> >; typename boost::enable_if_c<(((! boost::is_class<BOOST_MOVE_TEMPL_PARAM>::value) || (! boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value)) && (! boost::is_same<Key, BOOST_MOVE_TEMPL_PARAM>::value)), T&>::type = 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> > >&]'
./include/.h:240:23:   required from here
../boost/include/boost/container/string.hpp:218:22: error: no matching function for call to 'boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::allocator()'
../boost/include/boost/container/string.hpp: In instantiation of 'boost::container::container_detail::basic_string_base<Allocator>::members_holder::members_holder() [with Allocator = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]':
../boost/include/boost/container/string.hpp:104:18:   required from 'boost::container::container_detail::basic_string_base<Allocator>::basic_string_base() [with Allocator = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
../boost/include/boost/container/string.hpp:596:16:   required from 'boost::container::basic_string<CharT, Traits, Allocator>::basic_string() [with CharT = char; Traits = std::char_traits<char>; Allocator = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
../boost/include/boost/container/detail/value_init.hpp:31:13:   required from 'boost::container::container_detail::value_init<T>::value_init() [with T = 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/include/boost/container/flat_map.hpp:846:52:   required from 'boost::container::flat_map<Key, T, Compare, Allocator>::mapped_type& boost::container::flat_map<Key, T, Compare, Allocator>::priv_subscript(const key_type&) [with Key = short int; T = 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> > >; Compare = std::less<short int>; Allocator = boost::interprocess::allocator<std::pair<const short int, 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::flat_map<Key, T, Compare, Allocator>::mapped_type = 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::flat_map<Key, T, Compare, Allocator>::key_type = short int]'
../boost/include/boost/container/flat_map.hpp:469:4:   required from 'typename boost::enable_if_c<(((! boost::is_class<BOOST_MOVE_TEMPL_PARAM>::value) || (! boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value)) && (! boost::is_same<Key, BOOST_MOVE_TEMPL_PARAM>::value)), T&>::type boost::container::flat_map<Key, T, Compare, Allocator>::operator[](const BOOST_MOVE_TEMPL_PARAM&) [with BOOST_MOVE_TEMPL_PARAM = int; Key = short int; T = 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> > >; Compare = std::less<short int>; Allocator = boost::interprocess::allocator<std::pair<const short int, 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> >; typename boost::enable_if_c<(((! boost::is_class<BOOST_MOVE_TEMPL_PARAM>::value) || (! boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value)) && (! boost::is_same<Key, BOOST_MOVE_TEMPL_PARAM>::value)), T&>::type = 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> > >&]'
./include/.h:240:23:   required from here
../boost/include/boost/container/string.hpp:218:22: error: no matching function for call to 'boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::allocator()'

person trvecvlt    schedule 08.04.2015    source источник
comment
Не знаю, как я пропустил этот вопрос. В любом случае, пролистайте мои ответы с участием scoped_allocator_adaptor и uses_allocator, чтобы узнать, как облегчить боль.   -  person sehe    schedule 10.04.2015


Ответы (1)


Это потребовало некоторого копания. Ваша проблема в том, что flat_map::operator[] требует, чтобы сопоставленный тип T был конструируемым по умолчанию, потому что, если объект не существует, он должен иметь возможность вставить объект по умолчанию в это место.

Ваш ShmString не является конструируемым по умолчанию, потому что у него нет конструируемого распределителя по умолчанию (он должен использовать распределитель разделяемой памяти).

Таким образом, получается, что в вашем случае вы не сможете использовать operator[] и должны будете использовать другие методы, такие как insert, find и т. д.

person Mark B    schedule 08.04.2015