本文介绍了C ++提振共享内存ICL容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

林与升压:: ICL :: interval_map的作品完美的工作,但我想这个容器存储在共享内存。提升是否在共享内存存储的boost :: ICL容器提供支持。

Im working with boost::icl::interval_map that works perfectly but i want this container to be stored in shared memory. Does boost provide support for storing boost::icl containers in shared memory

    using namespace std;
    using namespace boost::icl;

    struct IFM {
           std::string destinationGroup;
           int priority;
           IFM()
           {
               destinationGroup= "";
               priority = 0;

           }

           IFM(const std::string& d, const int& p)
                 {
                     destinationGroup= d;

                     priority = p;

                 }


           IFM& operator +=(const IFM& right)
            {
                destinationGroup+= right.destinationGroup;
                priority += right.priority;
                return *this;
            }


        bool operator <(const IFM& left) const {
            if(priority <  left.priority)
                return true;
        }

        bool operator ==(const IFM& left) const {
            return destinationGroup== left.destinationGroup
                    && priority == left.priority;

        }

    };

    typedef std::set<IFM> guests;


    void boost_party()
    {
        interval_map<double, guests> party;

        IFM i = {"123", 1};
        IFM j = {"124", 1};
        IFM k = {"126", 2,};
        IFM l = {"128", 1};
        IFM m = {"129", 1};
        IFM n = {"130", 1};

        guests ii;
        ii.insert(i);

        guests jj;
        jj.insert(j);

        guests kk;
        kk.insert(k);

        guests ll;
        ll.insert(l);


        guests mm;
        mm.insert(m);

        party.add(make_pair(interval<double>::closed(12345600000,12345699999), guests(ii)));
        party.add(make_pair(interval<double>::closed(32100000000,32199999999), guests(jj)));
        party.add(make_pair(interval<double>::closed(42000000000,42999999999), guests(ll)));
        party.add(make_pair(interval<double>::closed(42101000000,42101099999), guests(kk)));
        party.add(make_pair(interval<double>::closed(67000000000,67999999999), guests(mm)));

        interval_map<double, guests>::const_iterator it;
        it = party.find(42101035898);

        if (it != party.end()) {
            interval<double>::type when = it->first;
            guests who = (*it++).second;
            cout << who.size() << endl;
            for (auto it2 : who) {
                    cout << when << ": " << it2.destinationGroup<< endl;
            }
        }
    }

int main() {
    boost_party();
    return 0;
}

给我下面的输出预计
现在,我米试图把一个简单的地图interval_map共享内存中第一,但我的code编译从不

Gives me following output which is expected Now i m trying to put a simple map interval_map in shared memory first but my code never compiles

boost::interprocess::managed_shared_memory segment(
     boost::interprocess::create_only, "MySharedMemory" //segment name
     , 65536);

     typedef int KeyType;
     typedef int MappedType;
     typedef pair<int,int> keyvalue;

     typedef boost::interprocess::allocator<keyvalue, boost::interprocess::managed_shared_memory::segment_manager>
     ShmemAllocator;

     ShmemAllocator alloc_inst (segment.get_segment_manager());

     typedef boost::icl::interval_map<int, int, boost::icl::partial_absorber, std::less, boost::icl::inplace_plus,boost::icl::inter_section, boost::icl::discrete_interval<int, std::less>, ShmemAllocator> MyMap;

给下面的错误

错误:类型/在模板参数列表参数值8不匹配的模板类比较,模板类结合,模板类科,每班间隔,模板类的Alloc>类boost :: ICL :: interval_map
   TYPEDEF提振:: ICL :: interval_map,ShmemAllocator> MyMap中;

error: type/value mismatch at argument 8 in template parameter list for ‘template class Compare, template class Combine, template class Section, class Interval, template class Alloc> class boost::icl::interval_map’ typedef boost::icl::interval_map, ShmemAllocator> MyMap;

错误:预期类模板,得到了'ShmemAllocator {又名提高::进程间::分配器,升压::进程间:: segment_manager,提高::进程间:: iset_index>>}

error: expected a class template, got ‘ShmemAllocator {aka boost::interprocess::allocator, boost::interprocess::segment_manager, boost::interprocess::iset_index> >}’

错误:无效的类型在之前的声明;令牌

error: invalid type in declaration before ‘;’ token

推荐答案

目前,编译器错误表明你传递一个的键入的作为模板参数,其中一个(可变参数)模板的模板论点的预期。

For now, the compiler error indicates that you're passing a type as a template argument, where a (variadic) template template argument was expected.

您可以在技术上实现,使用C ++模板11aliasing¹:

You could technically achieve that using C++11 template aliasing¹:

template <typename T> using allocator = bip::allocator<T, smgr>;
template<typename T>  using set       = std::set<T, allocator<T> >;

template <typename Domain, typename Codomain>
using basic_map = icl::interval_map<Domain, Codomain,
        icl::partial_absorber, std::less, icl::inplace_plus, icl::inter_section, icl::discrete_interval<int, std::less>,
        allocator
    >;

然而,这不会导致工作code正如我在livecoding会话已经找到。问题是,显然提升ICL目前不支持的状态分配器的。

这意味着,并非所有构造函数接受一个allocator实例所需的状态通过。

This means that not all constructors take an allocator instance to pass in the required state.

可悲的是,这意味着只有一个哈克自定义分配器可以想见的工作,那里的自定义分配器会参考你的共享内存段由一个全球性的参考。

Sadly, this means that only a hacky custom allocator could conceivably work, where the custom allocator would refer to your shared memory segment by a global reference.

下面是一个说明验证的概念,这样一个全球段分配器演示:

Here's a demo that shows proof-of-concept with such a global-segment allocator:

#include <boost/icl/interval_map.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <iostream>
#include <vector>
#include <set>

namespace bip = boost::interprocess;
namespace icl = boost::icl;

namespace shared {
    using segment = bip::managed_mapped_file;
    using smgr    = segment::segment_manager;
}

namespace {

    static bip::managed_mapped_file global_mm(bip::open_or_create, "./demo.bin", 1ul<<20);
    static bip::allocator<void, shared::smgr> global_alloc(global_mm.get_segment_manager());

    template <class T> struct SimpleAllocator : std::allocator<T> { // inheriting the nested typedefs only
        typedef T value_type;

        SimpleAllocator() : _alloc(global_alloc) {}
        template <class U> 
            SimpleAllocator(const SimpleAllocator<U> &other) : _alloc(other._alloc) {}

        T* allocate(std::size_t n)           { return std::addressof(*_alloc.allocate(n)); }
        void deallocate(T *p, std::size_t n) { _alloc.deallocate(p, n); }

        // optionals
        template <typename Other> struct rebind { typedef SimpleAllocator<Other> other; }; 
        bip::allocator<T, shared::smgr> _alloc;
    };

    template <class T, class U> bool operator==(const SimpleAllocator<T> &, const SimpleAllocator<U> &) { return true;  }
    template <class T, class U> bool operator!=(const SimpleAllocator<T> &, const SimpleAllocator<U> &) { return false; }
}

namespace shared {

    template <typename T> using allocator = SimpleAllocator<T>;
    template<typename T>  using set       = std::set<T, std::less<T>, allocator<T> >;

    template <typename Domain, typename Codomain>
    using basic_map = icl::interval_map<Domain, Codomain,
            icl::partial_absorber, std::less, icl::inplace_plus, icl::inter_section, icl::discrete_interval<int, std::less>,
            allocator
        >;

    using map      = basic_map<int, set<int> >;
    using interval = map::interval_type;
}

#include <iostream>

int main() {

    shared::map demo;
    for (auto&& element : {
            shared::map::value_type { shared::interval::right_open(4, 5), { 1, 7, } },
            shared::map::value_type { shared::interval::right_open(2, 6), { 1, 2, 3, } },
        })
    {
        demo.add(element);
        std::cout << "adding: " << element.first << ", result: " << demo << "\n";
    }
}

我用 managed_mapped_file 而不是 maneged_shared_memory ,因为后者没有在网上编译器的支持。

I used managed_mapped_file instead of maneged_shared_memory because the latter is not support on the online compiler.

¹或c。使用一个类型的函数++ 03

¹ or using a "type function" in c++03

这篇关于C ++提振共享内存ICL容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 09:32