Boost interprocess flat_map operator[] 编译错误

Posted

技术标签:

【中文标题】Boost interprocess flat_map operator[] 编译错误【英文标题】:Boost interprocess flat_map operator[] compilation errors 【发布时间】:2015-04-08 15:18:36 【问题描述】:

我正在对 boost::interprocess::flat_map 构建一些包装器,问题是,由于某种原因,我无法使用 operator[]at。当我使用findinsert 时,它编译成功。

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()'

【问题讨论】:

我不知道我是怎么错过这个问题的。 Anyhoops,请浏览我的answers involving scoped_allocator_adaptor and uses_allocator,了解缓解疼痛的技巧。 【参考方案1】:

这需要一些挖掘。您的问题是 flat_map::operator[] 要求映射类型 T 是默认可构造的,因为如果对象不存在,它需要能够在该位置插入默认对象。

您的ShmString不是默认可构造的,因为它没有默认的可构造分配器(它必须使用共享内存分配器)。

因此,在您的情况下,您将无法使用operator[],而必须使用其他方法,例如insertfind等。

【讨论】:

以上是关于Boost interprocess flat_map operator[] 编译错误的主要内容,如果未能解决你的问题,请参考以下文章

boost::interprocess_mutex 与进程本地 boost::mutex

boost::interprocess::interprocess_condition::wait 在等待时不会原子地解锁互斥锁

boost::interprocess::message_queue 权限被拒绝

Boost.interprocess Vector 作为类成员

这些 Boost::Interprocess 组件是不是需要同步?

Boost Interprocess 找不到 boost/config/user.hpp