3

Я использую boost 1.53 и GCC 4.1.2. Я попытался использовать boost unordered_map в некоторых тестах (документация говорит, что он должен работать с общей памятью), но я не могу скомпилировать свой код. С interprocess::map вместо неупорядоченного все в порядке.Boost interprocess unordered_map компиляция

: Определения типов

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; 

Распределение:

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

Использование:

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); 

А вот некоторая ошибка выхода:

../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> 

Я не уверен, что проблема в моем коде или из-за старой версии компилятора. Если проблема связана с компилятором, может ли она быть исправлена ​​с более новой версией boost? (я не могу обновить свой GCC). Или, может быть, есть некоторые реализации хэш-таблицы, совместимые с разделяемой памятью и с моим компилятором?

+3

не только ваш компилятор несколько лет неактуален, она [не официальный релизу] (HTTP: // StackOverflow .com/вопросы/23816420/что-это-GCC-4-1-3). Я серьезно пересмотрю, сможете ли вы его обновить. –

+0

@MikeSeymour, только что проверили, моя ошибка, я 4.1.2. Если бы это зависело от меня, чтобы выбрать версию GCC, я бы сразу ее обновил, но я ничего не могу с этим поделать. – trvecvlt

+0

'boost :: interprocess :: string' ** не ** автоматически разделяется (он не использует межпроцессорные распределители, если вы не сообщите об этом). То же самое для 'bip :: map' Опубликовать SSCCE. Ваш образец не является самодостаточным. – sehe

ответ

2

Вот исправленная версия.

Я просто попытался сделать это самостоятельно в соответствии с наводящими комментариями. И это работает.

Надеется, что это помогает в любом случае:

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); 
} 
+0

Какую версию GCC вы используете? Существует 'auto', поэтому думаю, что это довольно современный =) Код выглядит правильно, но на моем GCC 4.1.2 я получаю те же ошибки. Кажется, единственный вариант для меня - это попробовать новый толчок или просто использовать карты. – trvecvlt

+1

Я предполагаю, что вы заменили auto именем типа? Уверены ли вы, что у вас нет «использования пространства имен», разрушающего хаос? (Даже если они встроены в какое-либо пространство имен в заголовке) fyi У распределителей есть конструкторы преобразования (неявные повторы), и вы можете их неявно строить из 'mmf.get_segment_manager()' тоже. Также см. Комментарий по предыдущему вопросу. – sehe

+0

Подождите секунду. Поддержка 'auto' была выпущена в [GCC 4.4, с 21 апреля 2009 г.] (https://gcc.gnu.org/gcc-4.4/changes.html).Я не вижу, как «6 лет» приравнивается к «довольно современному») « – sehe